pthread_cond_wait() and signal, the result depend on OS

二次信任 提交于 2021-01-27 18:02:49

问题


I am a beginner of multi-threaded programming, and now I know that when a signal was sent while waiting with pthead_cond_wait(), the result depends on the OS. Can somebody tell me how to know how the call was interrupted, and how to write portable code?

#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 

When using Solaris native cond_wait(), it returns EINTR as documented. Is there any idea how to know that pthread_cond_wait() was interrupted?


回答1:


POSIX specifies that this function will never return EINTR. For portability to legacy OSes you can check for it anyway, it doesn't hurt

More importantly, you should be prepared for spurious wakeups. The function can return zero at any time for any reason wiith the condition not being met. The mutex will be locked. You have to check the condition and, if not met, go back to pthread_cond_wait.




回答2:


I read the Linux pthread_cond_wait's man manual, it says:

If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup.

I guess other OS's also have manuals to help you figure it out.




回答3:


Thank you very much for everyone. Now I know that with using signal to stop long waiting condition do not work. pthread_cond_wait() resume waiting for the condition as if it was not interrupted, or it returns zero due to spurious wakeup. Then I want to do that, I will need a second lock like

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;

Regards,



来源:https://stackoverflow.com/questions/39242148/pthread-cond-wait-and-signal-the-result-depend-on-os

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!