指示进程中的所有线程
在不保留当前线程列表的情况下,我试图看到实时信号传递给我的进程中的所有线程。 我的想法是这样做:
pthread_sigmask
),并进入一个重复调用raise(sig)
的循环,直到sigpending
指示信号处于挂起状态(信号被阻塞时没有剩余线程)。 我遇到的问题是pthread_sigmask
没有得到尊重。 如果我在strace
下运行测试程序(大概是由于不同的调度时序),但一旦我单独运行测试程序,发送者就会收到它自己的信号(尽管屏蔽了它..?),而其他线程永远得到预定。
任何想法可能是错误的? 我尝试过使用sigqueue
来代替raise
,探测信号掩码,在所有地方添加sleep
以确保线程耐心地等待他们的信号,等等,现在我不知所措。
编辑:感谢psmears的回答,我想我明白了这个问题。 这是一个潜在的解决方案。 反馈会很好:
num_threads
信号,然后解除阻塞自身的信号。 num_threads
返回。 num_threads
,然后释放该锁。 一个可能的问题是,如果内核内存不足,信号不会排队(Linux似乎有这个问题)。 你知道sigqueue
可靠地通知调用者何时无法对信号进行排队(在这种情况下,我会循环直到成功),或者信号可能会悄无声息地丢失?
编辑2:它现在似乎在工作。 根据sigqueue
的文档,如果它无法排队信号,它会返回EAGAIN
。 但为了健壮性,我决定继续调用sigqueue
直到num_threads-1
信号处理程序正在运行, sched_yield
在发送num_threads-1
信号后将调用交织到sched_yield
。
线程创建时有一个竞争条件,计算新线程,但我用一个奇怪的(ab)使用读写锁来解决它。 线程创建是“读取”,广播信号是“写入”,所以除非线程试图广播,否则它不会在线程创建时产生任何争用。
raise()
将信号发送给当前线程(仅),所以其他线程不会收到它。 我怀疑,事实strace
使事情的工作是在一个错误strace
(因为它的工作原理它结束了拦截发送到进程和所有信号再次提高他们的方式,所以它可能是在错误的方式重新认识他们...)。
你可以使用kill(getpid(), <signal>)
将信号发送到当前进程作为一个整体。
但是,您可能会看到另一个潜在的问题,即sigpending()
可能表示信号在所有线程接收到该信号之前处于挂起状态 - 这意味着该进程至少有一个此类信号待处理,并且没有CPU已经可以运行一个线程来传递它...
你能描述一下你打算实现的更多细节吗? 你想要它是多么便携? 几乎肯定有更好的方法来做到这一点(信号几乎总是令人头疼的事情,尤其是当与线程混合在一起时......)
在多线程程序中,raise(sig)相当于pthread_kill(pthread_self(),sig)。 试试kill(getpid(),sig)
考虑到你可以明显地锁定线程的创建和销毁,你可不只是让“广播”线程在每线程队列中发布所需的更新到线程本地状态,每当线程去使用线程时,本地状态? 如果有未完成的更新,则首先应用它们。
链接地址: http://www.djcxy.com/p/50019.html上一篇: Signalling all threads in a process
下一篇: How does a process come to know that it has received a signal