我正在阅读http://250bpm.com/blog:12以了解应如何/可以处理EINTR,而我无法将第二个和第三个源代码段与说明进行协调。
第二次上市:
volatile int stop = 0;
void handler (int)
{
stop = 1;
}
void event_loop (int sock)
{
signal (SIGINT, handler);
while (1) {
if (stop) {
printf ("do cleanup\n");
return;
}
char buf [1];
recv (sock, buf, 1, 0);
printf ("perform an action\n");
}
}
第三次上市:
volatile int stop = 0;
void handler (int)
{
stop = 1;
}
void event_loop (int sock)
{
signal (SIGINT, handler);
while (1) {
if (stop) {
printf ("do cleanup\n");
return;
}
char buf [1];
int rc = recv (sock, buf, 1, 0);
if (rc == -1 && errno == EINTR)
continue;
printf ("perform an action\n");
}
}
具体做法是:
POSIX规范定义当捕获信号(例如Ctrl + C)时,recv返回EINTR错误。这允许事件循环换行并检查“停止”。变量:
但是第二个列表中假设阻塞的解释是:
问题是recv是一种阻塞功能。如果按下Ctrl + C 虽然事件循环在recv中被阻止,但你会得到一种 死锁:信号处理程序按预期执行,它设置“停止”'到1, 但随后执行阻止。事件循环卡在recv中并具有 没有机会检查是否“停止”'被设为1。
嗯,在两种情况下都定义了信号处理程序,因此SIGINT
被捕获,因此看起来recv
在两种情况下都应该解锁,不是吗?