2011-08-03 64 views
3

有一个拥有两个线程守护程序:TH1,TH2。 th2使用read(2)读取套接字。处理两个结果SIGTERMs

如果我杀死守护进程SIGTERM,th1捕获并处理信号(设置终止标志),之后守护进程析构函数被调用,它调用pthread_kill(th2, SIGTERM)。然而,第二个线程不接收SIGTERM,因此它不会被杀(当套接字接收数据,并从read()失控,它执行完毕,作为终止标志已设置)。

如果我打电话pthread_kill(th2, SIGUSR2),然后pthread_kill(th2, SIGTERM),一切都正确完成。因此,UNIX似乎不允许发送相同的信号。

难道这种行为取决于操作系统?我们能否确保指定的线程从另一个线程接收到SIGTERM

+1

如果包括适当的编程语言的标签,C,C++,或yourLanguageHere你会得到更多的“眼睛”上你的问题。祝你好运。 – shellter

+2

谢谢,添加了标签。我认为unix的意思是C) – vissi

+2

@vissi:这是错误的。您应该只包含您工作语言的标签。除非你的问题涉及互操作性,否则你只能标记一种语言。 – Puppy

回答

5

的Unix并允许发送多个连续信号的处理,但如果该信号被发送靠得太近,或一个附加的信号被被送到一个已经未决信号交付之前的过程中,则多个信号可以被连接成一个单一的信号事件。

还要记住的是,虽然pthread_kill()将信号发送到一个给定的线程中处理,所述信号的实际处理具有全局效果(即,信号处理程序是每个进程,而不是每线程)。

您可能还需要寻找到显式调用pthread_cancel()因为read()是一个有效的取消点。如果需要,您可以添加取消处理程序,并且如果您使用的功能不是取消安全的,则可以阻止线程的取消状态。您可以阅读关于使用pthread_cancel()here的一些提示。

+0

'sigaction()'和SA_SIGINFO与POSIX实时信号排队行为非常正交 - 说他们“启用”实时语义是不准确的。此外,误导性地建议可以在运行时启用这些语义。实时信号(SIGRTMIN .. SIGRTMAX)总是排队,而标准信号不会。 (该规范允许他们,但在实践中,他们不这样做) – pilcrow

+0

好的,这就是我的困惑......从规格出发(而不是像Linux中所实现的那样),似乎是标准的如果您使用'sigaction()'为标准信号类型设置SA_SIGINFO,那么除了实时信号之外,信号也会排队。感谢您澄清这一点...我会更新我的答案。 – Jason

1

一个比较老派,但有效的方法是使用select()和管道重新调度信号的所有线程。 (你在阻塞句柄上选择()管道读取句柄)。