【问题标题】:pthread_cond_wait() and signal, the result depend on OSpthread_cond_wait() 和信号,结果取决于操作系统
【发布时间】:2016-08-31 06:24:10
【问题描述】:

我是一个多线程编程的初学者,现在我知道当用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() 被打断了?

【问题讨论】:

    标签: c linux multithreading macos solaris


    【解决方案1】:

    POSIX 指定此函数永远不会返回 EINTR。对于遗留操作系统的可移植性,您无论如何都可以检查它,它没有伤害

    更重要的是,您应该为虚假唤醒做好准备。在不满足条件的情况下,该函数可以随时出于任何原因返回零。互斥体将被锁定。您必须检查条件,如果不满足,则返回 pthread_cond_wait。

    【讨论】:

    • 亲爱的 n.m.谢谢您的回答。也许你想告诉我 [ pthread_mutex_lock();而(条件_is_false)pthread_cond_wait(); pthread_mutex_unlock(); ]
    • 是的,这就是模式。
    【解决方案2】:

    我阅读了 Linux pthread_cond_wait 的手册,上面写着:

    如果将信号传递给等待条件变量的线程,则在从信号处理程序返回后,线程将继续等待条件变量,就好像它没有被中断一样,否则由于虚假唤醒它应该返回零。

    我猜其他操作系统也有手册可以帮助您弄清楚。

    【讨论】:

    • 亲爱的 barcelona_delpy,感谢您的回答。我阅读了 Linux 的日文版手册,它说 pthread_cond_timedwait 在发出信号时返回 EINTR。我会找一些手册,只有SUS3手册告诉返回错误。然后我必须在 MacOS X 和 Solaris、SUS3 上等待条件时阻止信号。问候,
    【解决方案3】:

    非常感谢大家。 现在我知道使用信号停止长时间等待条件不起作用。 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;
    

    问候,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-15
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多