pthread条件信号是否与POSIX实时信号相同或不同?

时间:2018-02-26 01:42:28

标签: c pthreads signals posix

我正在学习OS类中的pthread和信号,我有一个问题:pthread_cond_signal的基础信号机制只是一个标准的POSIX实时信号,它适合于唤醒任务等待线程?或者是否有其他机制碰巧使用相同的术语来描述两种不同的想法?

如果它们是相同的,我应该能够告诉线程使用pthread_cond_waitpthread_kill唤醒,对吗?我可以以某种方式改变一个线程的信号掩码,以便在它应该接收来自pthread_cond_signal的信号时?我意识到这些是糟糕的编码实践和黑客尝试的东西,但我只是想了解pthread等待/信号过程的基本机制。

我试过阅读算法here,但它有点过头了。我的猜测是他们不同,但我只想确定。

2 个答案:

答案 0 :(得分:3)

虽然在谈到这两种机制时都使用了术语“信号”,但POSIX实时信号和pthread条件变量是不同的。

POSIX或操作信号是relatively rich semantics and history的“软件中断”。除SIG_IGN外,它们可能会被忽略(sa_sigaction),已发送( accepted ),blockedwhen they can't be。他们可能有own stack用于用户定义的处置,尽管在处理过程中可以安全地进行处理is quite limited。他们可能会瞄准an individual threadat a whole process。他们会中断some functions,但not others,有时由最终用户自行决定(SA_RESTART)。实时扩展允许signals to queue并可能提供word of data。还有更多。

相比之下,POSIX pthread条件变量synchronization mechanisms保护了一些谓词。这里,“signal”是用户启动的唤醒一个线程等待条件变量的动作,如果这样的线程存在的话。

当我们谈论这些机制时,同样的术语在不同的意义上被使用也许是不幸的,但事实也是如此。

答案 1 :(得分:0)

pthread_kill无法唤醒正在等待条件变量的线程,它会用swag杀死该线程,并且该线程中的其余代码将不会执行

#include <stdio.h>
#include <signal.h>
#include <pthread.h>

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t conditionVar ;

int cond = 1;
int execWait = 1;

void * killSig( void * arg ) {
  puts("thread killSig");
  for ( int i = 0; i <= 10; i++ )
    printf("%d\n", i);

  pthread_kill(pthread_self(), 9); // control stops here, it kills a thread completely, the puts call will not print
  puts("this would not print");
}


void * condition( void * arg ) {
  puts("thread cond");
  execWait = 0;
  if ( cond == 1 ) {
    pthread_cond_wait(&conditionVar, &lock);
  }
  // if pthread_cond_signal(pthread_cond_t *_cond) is called,
  // control continues here
  for ( int i = 0; i <= 10; i++ ) {
    printf("%d\n", i);
  }
  puts("this will print");
}

void * wake( void * arg ) {
  while ( execWait == 1 )
      ;
  cond = 0;
  pthread_cond_signal(&conditionVar);
}

int main() {

  pthread_t tid1;
  pthread_t tid2;

  pthread_t wakeThread;


  pthread_create(&tid1, NULL, killSig, NULL);
  pthread_create(&tid2, NULL, condition, NULL);

  pthread_create(&wakeThread, NULL, wake, NULL);

  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  pthread_join(wakeThread, NULL);

}

编译
$ gcc testPthread.c -o testPthread -std=gnu11 -lpthread -g