因此,当我中断程序(使用SIGINT)时,我试图优雅地关闭循环中的多个线程。现在,我使用一个回调来更改shared_ptr(已复制到每个线程)的状态,以向所有其他线程指示是时候打破循环了(线程在每次迭代中检查一下shared_ptr的状态)。这行得通,但是我想知道这是否是“好的”编程实践?
答案 0 :(得分:1)
否,不能保证在信号处理程序中修改共享指针是安全的。跨多个线程修改共享指针也不是安全的(复制尽管修改了内部状态也很安全)
比较安全的是将volatile std::sig_atomic_t
用作标志并在信号处理程序中对其进行修改。但是,sig_atomic_t
不保证与处理信号的线程同步。
如果您可以依靠std::atomic<bool>
是无锁的(标准不保证),则在信号处理程序中进行修改以及保证线程同步也将有效。
否则,您可以将本地线程volatile std::sig_atomic_t
用于信号处理程序,一旦在一个线程中检测到更改,就使用辅助线程同步方法(原子,条件变量等)将信息广播到其他线程。 )。
另一种方法:您可以让一个线程简单地等待信号(不需要sig-atomic标志),并且一旦接收到该线程,便继续进行线程同步广播(与先前建议中的第二阶段相同)。注意,该信号必须被其他线程屏蔽,以便等待线程处理。但是,在标准C ++中没有好的API可以等待信号。如果可以依靠的话,POSIX标准中有sigwait
。