exit()函数无法退出进程

exit() function fails to exit process

本文关键字:退出 进程 函数 exit      更新时间:2023-10-16

我正在使用FreeGLUT在Linux中开发一个多线程C++应用程序。奇怪的是,在我的一个线程中调用exit()会导致onexit()回调被调用并完成,但无法退出我的程序。相反,根据GDB的说法,它挂在GLUT库中的select()调用中。

我还有一个键盘回调,当我按下"q"时就会退出。如果在程序挂起时按"q",GLUT将正常退出。

似乎没有人有类似的问题。文档中说exit()应该关闭整个进程,而不仅仅是一个线程,所以事实并非如此。我被难住了。你有什么想法吗?

编辑:我发现问题了。我错了,出口处理程序已经完成了。库函数调用正在等待一个互斥对象,该互斥对象在调用exit()时已被锁定。GLUT只是利用了空闲时间。感谢大家的回复。

在C++03中

注意:exit()是一个C函数。

作为一种语言,C在语言级别上没有线程的概念
线程通常通过库支持添加到C中。因此,您需要阅读库文档,了解从非主线程调用exit()的影响。

它可能无法跨线程实现进行移植。

最好只从主线程调用exit()
在子线程中,您可能只需要设置一些由主线程查看的状态。让主线程看到这个状态并手动调用exit。注意,如果一些线程库是仍在运行的子线程,那么即使在man线程上调用exit也可能挂起它们。因此,如果您希望代码是可移植的,最好让主线程在退出之前等待所有子线程。

在C++11中

既然C++11已经进入了,因为在该语言中有了显式线程,它还有更多。See n3376 Section 18.4.1 [cstdint.syn] Paragraph 8

函数exit()在这个国际标准中有额外的行为:

--首先,销毁具有线程存储持续时间并与当前线程相关联的对象。接下来,将销毁具有静态存储持续时间的对象,并调用通过调用atexit注册的函数。

      See 3.6.3 for the order of destructions and calls. (Automatic objects are not destroyed as a result of calling exit().)
      If control leaves a registered function called by exit because the function does not provide a handler for a thrown exception, std::terminate() shall be called (15.5.1).

--接下来,所有具有未写入缓冲数据的打开的C流(由中声明的函数签名介导)都将被刷新,所有打开的C流量都将被关闭,并且通过调用tmpfile()创建的所有文件都将被删除。

--最后,将控制权返回到主机环境。若状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。若状态为EXIT_FAILURE,则返回状态不成功终止的实现定义形式。否则,返回的状态是实现定义的。