Ris*_*ain 31 c++ multithreading signals exit
我正在我的程序中创建多个线程.按下时Ctrl-C,将调用信号处理程序.在一个信号处理程序里面,我exit(0)
终于放了.问题是,有时程序安全终止,但有时,我得到运行时错误说明
abort() has been called
Run Code Online (Sandbox Code Playgroud)
那么避免错误的可能解决方案是什么?
Som*_*ude 30
通常的方法是设置一个由所有线程(包括主线程)检查的原子标志(如std::atomic<bool>
).如果设置,则子线程退出,主线程开始到join
子线程.然后你可以干净利落地退出.
如果您使用std::thread
线程,这可能是您崩溃的原因.join
在std::thread
对象被破坏之前必须有线程.
Jer*_*ner 14
其他人已经提到让信号处理程序设置为a std::atomic<bool>
并让所有其他线程定期检查该值以知道何时退出.
只要所有其他线程以合理的频率周期性地唤醒,那么这种方法效果很好.
如果你的一个或多个线程纯粹是事件驱动的,那就不完全令人满意了 - 但是在一个事件驱动的程序中,线程只有在它们有一些工作要做时才会被唤醒,这意味着它们可能很好一次睡几天或几周.如果他们被迫每隔(这么多)毫秒被唤醒只是为了轮询一个原子布尔标志,这使得一个非常高CPU效率的程序的CPU效率更低,因为现在每个线程都以很短的规则间隔唤醒, 24/7/365.如果您试图节省电池寿命,这可能会特别成问题,因为它可能会阻止CPU进入省电模式.
避免轮询的另一种方法是:
select()
fd_set中包含接收套接字(或采取类似的操作poll()
或线程阻塞的等待IO函数)select()
调用立即返回,FD_ISSET(receivingSocket)
由于收到的字节,指示为truejoin()
每个子线程,以便可以保证所有子线程在 main()返回之前实际上已经消失.(这是必要的,因为否则存在竞争条件的风险 - 例如,post-main()清理代码可能偶尔释放资源,而仍在执行的子线程仍在使用它,导致崩溃)Yak*_*ont 10
你必须接受的第一件事是线程很难.
"使用线程的程序"与"使用内存的程序"一样通用,你的问题类似于"如何使用内存破坏程序中的内存?"
处理线程问题的方法是限制线程的使用方式和线程的行为.
如果您的线程系统是由数据流网络组成的一堆小操作,则隐含保证如果操作太大,则会将其分解为较小的操作和/或与系统进行检查点,然后关闭看起来非常不同比如果你有一个线程加载一个外部DLL,然后运行它从1秒到10小时到无限长度的某个地方.
像C++中的大多数东西一样,解决你的问题将是关于所有权,控制和(最后的手段)黑客攻击.
与C++中的数据一样,每个线程都应该被拥有.线程的所有者应该对该线程有很大的控制权,并且能够告诉它应用程序正在关闭.关闭机制应该是健壮的并且经过测试,并且理想地连接到其他机制(例如早期中止投机任务).
你调用exit(0)的事实是一个坏兆头.它意味着您的主要执行线程没有干净的关闭路径.从那里开始; 中断处理程序应该通知主线程应该开始关闭,然后你的主线程应该正常关闭.所有堆栈帧都应该展开,数据应该清理,等等.
然后,同样类型的逻辑允许干净和快速关闭也应该应用于您的线程代码.
有人告诉你它就像条件变量/原子布尔一样简单,并且轮询正在向你出售货物清单.如果你很幸运,那只会在简单的情况下起作用,并且确定它是否可靠地工作会非常困难.