我是多线程编程的初学者,现在我知道在等待pthead_cond_wait()
时发送信号时,结果取决于操作系统。
有人能告诉我如何知道调用是如何被中断的,以及如何编写可移植代码?
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
void
sigusr1_handler(int sig)
{
printf("signal called\n");
}
int
main()
{
int n;
pthread_mutex_t mut;
pthread_cond_t cond;
struct timespec ts;
signal(SIGUSR1, sigusr1_handler);
pthread_mutex_init(&mut, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&mut);
printf("before cond_wait\n");
n = pthread_cond_wait(&cond, &mut);
printf("after pthread_cond_wait : %d\n", n);
perror("error pthread_cond_wait:");
pthread_mutex_unlock(&mut);
return 0;
}
MacOS X 10.11.4
cc -o condwait condwait.c -lpthread
Linux 2.6.32-642.3.1.el6.x86_64
gcc -o condwait condwait.c -lpthread
Solaris11 5.11 11.2
cc -D_POSIX_C_SOURCE -D_REENTRANT -mt -o condwait condwait.c -lpthread
MacOS X
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait:: Unknown error: 260
Solaris
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait : Error 0
Linux
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
$ jobs
[1]+ Running
使用Solaris本机cond_wait()
时,它会返回EINTR
,如文档所述。
有什么想法知道pthread_cond_wait()
被打断了吗?
答案 0 :(得分:2)
POSIX指定此函数永远不会返回EINTR。对于遗留操作系统的可移植性,无论如何都可以检查它,它不会造成伤害
更重要的是,你应该为虚假的唤醒做好准备。该函数可以在任何时候因任何原因而无法满足条件时返回零。互斥锁将被锁定。您必须检查条件,如果不满足,请返回pthread_cond_wait。
答案 1 :(得分:1)
我读了Linux pthread_cond_wait
的手册,它说:
如果信号被传递给等待条件变量的线程,则从信号处理程序返回时,线程将继续等待条件变量,就像它没有被中断一样,或者由于虚假唤醒而返回零。
我猜其他操作系统也有手册可以帮助你搞清楚。
答案 2 :(得分:0)
非常感谢大家。 现在我知道使用信号停止长时间等待状态不起作用。 pthread_cond_wait()恢复等待条件,好像它没有被中断,或者由于虚假唤醒而返回零。 然后我想这样做,我需要第二个锁,如
pthread_mutex_lock(&mut);
while(condition_is_false) {
n = pthread_cond_timedwait();
if (n == ETIMEDOUT) {
pthread_mutex_lock(&mut2);
if (condition2_is_true) {
pthread_mutex_unlock(&mut2);
pthread_mutex_unlock(&mut);
return STOPPED;
}
pthread_mutex_unlock(&mut2);
}
}
pthread_mutex_unlock(&mut);
return 0;
此致