POSIX线程/信号:用于确定信号传递到哪个线程的便携方式?

时间:2011-12-27 21:55:03

标签: c multithreading posix signals

我有一个多线程服务器(使用POSIX线程),每个持久连接都有一个线程。在其中一个线程中,连接的另一端关闭,导致交付SIGPIPE。是否有一个(最好是可移植的)确定发生了哪个线程(以及哪个连接)因此我可以让我的信号处理程序执行线程/连接清理工作本身或设置一个标志,以便主线程和工作线程分别看到他们需要以后再做吗?

编辑:我想知道我是否可以使用& errno,将其存储在全局数组中并将其与服务器的线程标识符相关联,然后在信号处理程序中搜索& errno。线程的特定错误是否对信号处理程序可见?我是否理解线程安全errno如何在球场中工作?

4 个答案:

答案 0 :(得分:12)

我不这么认为,不。对多线程服务器更好的解决方案是抑制SIGPIPE信号(通过调用signal(SIGPIPE, SIG_IGN)作为程序启动例程的一部分)然后让线程处理由返回的错误值(-1 / EPIPE)而是send()

信号和多线程不能很好地混合。

答案 1 :(得分:1)

您可以在信号处理程序中安全地使用pthread_self。它是async-signal-safe

这个答案适用于后人。我不会在技术上推荐这种方法。其他答案和评论,建议采用不同的方法,将更好地实施。

在提出这个问题的时候,pthread_self的安全性并不一定是显而易见的。 POSIX:2008技术勘误1,日期为2013年(在提出此问题两年后),明确pthread_self明确表示异步信号安全,如Linux signal(7) man page所述。

相关地,你在评论中提到,你不确定"内核是否将[一个SIGPIPE]发送给任何没有被阻止的线程" 。这是一个很好的问题 - 它是一个过程导向的信号还是一个线程导向的信号? - 谢天谢地,放错了地方。内核生成的SIGPIPE是"同步生成的#34;信号响应一些I / O调用,并发送到调用线程。在POSIX:2001的勘误表2(2004)中明确阐明了这一点,即回应write的SIGPIPE是"sent to the thread"(强调添加)。

答案 2 :(得分:0)

我的方法是让SIGPIPE的信号处理程序只将其线程ID写入全局变量,并使用其他一些机制向线程发出信号,应该处理它。

答案 3 :(得分:0)

如何使用全局变量(声明的线程局部)来存储线程id,在线程创建时初始化它并在线程的信号处理程序中引用它。

有关GCC的详细信息,请参阅此处:http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html或更多一般信息:http://en.wikipedia.org/wiki/Thread-local_storage