Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使用阻塞调用时如何退出程序_Multithreading_Sockets_Destructor_Exit_Blocking - Fatal编程技术网

Multithreading 使用阻塞调用时如何退出程序

Multithreading 使用阻塞调用时如何退出程序,multithreading,sockets,destructor,exit,blocking,Multithreading,Sockets,Destructor,Exit,Blocking,我需要做一个项目,应用程序监控传入的连接,并应用xml文档中定义的一些规则。这些规则要么过滤(阻止或允许)连接,要么重定向某个端口上的流量。为此,我使用了accept和recv(来自Winsock)等函数。所有这些函数都在不同的线程上使用。不过,我想知道,既然所有这些阻塞调用都已发出,我应该如何在退出之前清理程序。通常,我要么等到用户通过X按钮退出控制台,要么等待用户在主线程中输入某个字符。问题是,我不确定如果应用程序在仍有活动线程/内存仍在分配/套接字正在使用时退出会发生什么。所有的析构函数都

我需要做一个项目,应用程序监控传入的连接,并应用xml文档中定义的一些规则。这些规则要么过滤(阻止或允许)连接,要么重定向某个端口上的流量。为此,我使用了accept和recv(来自Winsock)等函数。所有这些函数都在不同的线程上使用。不过,我想知道,既然所有这些阻塞调用都已发出,我应该如何在退出之前清理程序。通常,我要么等到用户通过X按钮退出控制台,要么等待用户在主线程中输入某个字符。问题是,我不确定如果应用程序在仍有活动线程/内存仍在分配/套接字正在使用时退出会发生什么。所有的析构函数都被调用了吗?手柄和插座是否正确关闭?还是我需要自己去做


谢谢

总的来说,我会说不。不要尝试显式地清理资源,如套接字、fd、句柄和线程,除非您完全被迫这样做

确切的行为取决于操作系统和您终止应用程序的方式

当进程终止时,所有通用桌面操作系统将释放操作系统分配给进程的资源。这包括套接字、文件描述符和内存

在Windows/Linux上,如果从C/C++main()返回而没有任何显式清理,静态DTOR将被crt代码调用。非主线程中动态分配对象的DTR不运行

用其他语言编写的可执行文件可能会有不同的行为

如果不从main()返回,而是直接调用“ProcessExit()”API,则不会调用静态析构函数,因为操作系统没有DTOR的概念-它不知道或不感兴趣生成可执行文件所使用的语言

无论哪种情况,都会调用操作系统来终止进程。操作系统通过首先更改所有未运行的进程线程的状态,使其不再运行来实现这一点(简单的“Dummies”版本:)。然后停止在其他内核上运行的线程。然后关闭fd、套接字等操作系统资源,然后释放,然后释放所有进程内存,然后释放操作系统内核进程/线程对象,然后进程不再存在

如果您确实需要一些或全部C++/当某些线程需要停止应用程序时调用的任何DTR,那么您必须明确地通知其他线程停止,以便DTR可以运行。我倾向于使用一个全局可访问的“CloseRequested”bool,在返回后立即检查相关的阻塞呼叫。仍然存在说服阻塞呼叫返回的问题

一些阻塞调用可以被编码为等待多个信号,因此允许调用通过简单的事件/sema/condvar/任何信号返回

某些调用,如recv()、accept(),可以通过关闭它们正在等待的fd/socket来避免提前返回

某些调用可以通过“人为”满足其等待条件来返回-例如,创建临时文件只是为了使文件夹监视器调用返回,以便可以检查“CloseRequested”bool

如果阻塞调用非常顽固,以至于无法说服它返回,那么您可以重新设计应用程序,使DTOR中释放的关键资源可以由另一个线程释放-可能在另一个线程中创建该对象,并将其传递给在ctor参数中阻塞的线程,类似的事情


请注意:上面列出的线程关闭代码bodges是额外的代码,不会添加到应用程序的正常功能中。您应该将显式线程关闭限制为那些持有资源的线程,这些资源绝对必须由显式用户代码-数据库连接释放。如果操作系统可以释放资源,那么应该允许它这样做。操作系统非常擅长在释放正在使用的资源之前停止所有进程线程,用户代码则不然。

在可能的情况下,使用带有超时值的阻塞调用,并让线程循环。这为您提供了一个检查关机条件并优雅地退出线程的位置。当进程退出时,系统通常会清理句柄。优雅地关闭套接字是礼貌的,但不是绝对强制的。不这样做的缺点是内核可能需要一段时间来清理独占资源。例如,如果您只是杀死一个等待accept()的线程,然后应用程序重新启动,那么在内核清除旧套接字之前,它将无法在同一端口上成功地接受()