我正在使用FreeGLUT在Linux中处理multithreading的C ++应用程序。 奇怪的是,在我的一个线程中调用exit()会导致onexit()callback被调用并完成,但是无法退出我的程序。 相反,它依据GDB在GLUT库中的select()调用中挂起。
我也有一个键盘callback,当我按'Q'时退出。 如果在程序挂起时按下“q”键,GLUT就会退出。
没有人似乎有类似的问题。 文档说exit()应该closures整个进程,而不仅仅是一个线程,所以不是这样。 我很难过 你有什么想法?
编辑:我发现了这个问题。 退出处理程序已经完成,我错了。 一个库函数调用正在等待在调用exit()时已被locking的互斥锁。 GLUT只是利用了空闲时间。 谢谢大家的回应。
注意:exit()是一个C函数。
C作为一种语言在语言层面上没有线程的概念。
线程通常通过库支持添加到C中。 所以你需要从不是主线程的线程读取调用exit()影响的库文档。
它可能不能通过线程实现移植。
你最好的选择是只从主线程调用exit()。
在一个子线程中,你应该设置一些被主线程查看的状态。 让主线程看到这个状态并手动调用退出。 请注意,即使调用man线程上的退出可能会挂起一些线程库,如果它们仍然在运行的子线程。 所以最好是让主线程在退出之前等待所有的孩子,如果你想要你的代码是可移植的。
既然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,则返回状态不成功终止的实现定义形式。 否则,返回的状态是实现定义的。