编辑:我想知道是否可以使用&errno,在全局数组中存储它并将其与线程的标识符相关联,然后在信号处理程序中搜索&errno。线程特定的errno是否对信号处理程序可见?我对线程安全的errno的理解是否正确?
我不这么认为。对于多线程服务器,更好的解决方案是在程序启动时通过调用signal(SIGPIPE, SIG_IGN)
来禁止SIGPIPE
信号,并让线程处理send()
返回的错误值(-1/EPIPE)。
信号和多线程不太兼容。
SIGPIPE
信号,改为处理 EPIPE
错误。@SteelyDan: SIGPIPE
信号并不会比 EPIPE
更快地被处理 - 该信号只会在会否发生 EPIPE
错误时生成。 - caf您可以在信号处理程序中安全地使用pthread_self
。它是异步信号安全的。
这个答案是为了后人而留下的。我不建议从技术上采用这种方法。其他回答和评论提出的不同方法将更好地实现。
当时提出这个问题时,pthread_self
的安全性并不明显。 POSIX:2008技术勘误1于2013年(此问题提出两年后)发布,澄清了pthread_self
明确是异步信号安全的,如Linux signal(7) man page中所述。
相关地,您在评论中提到您不确定"内核是否向任何没有阻塞的线程发送[SIGPIPE]"。这是一个很好的担忧——它是进程定向信号还是线程定向信号?——幸运的是,这是一个错误的担忧。内核生成的SIGPIPE是响应某些I/O调用而"synchronously generated"的信号,并发送到调用线程。这在Corrigendum 2(2004)中明确说明,POSIX:2001的SIGPIPE响应write
时"发送到线程"(强调添加)。
使用全局变量(声明为线程本地)来存储线程ID,创建线程时初始化它,并在线程的信号处理程序中引用它,这个方案怎么样?
有关GCC的详细信息,请参见此处:http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html 或更一般的信息请参见此处:http://en.wikipedia.org/wiki/Thread-local_storage
我的方法是为SIGPIPE的信号处理程序编写一个将其线程ID写入全局变量的函数,并使用其他机制向应该处理它的线程发出信号。
pthread_self
是安全的轶事证据,但我仍在寻找明确的参考资料。 - CB Bailey