我正在学习OS类中的pthread和信号,我有一个问题:pthread_cond_signal
的基础信号机制只是一个标准的POSIX实时信号,它适合于唤醒任务等待线程?或者是否有其他机制碰巧使用相同的术语来描述两种不同的想法?
如果它们是相同的,我应该能够告诉线程使用pthread_cond_wait
从pthread_kill
唤醒,对吗?我可以以某种方式改变一个线程的信号掩码,以便在它应该接收来自pthread_cond_signal
的信号时?我意识到这些是糟糕的编码实践和黑客尝试的东西,但我只是想了解pthread等待/信号过程的基本机制。
我试过阅读算法here,但它有点过头了。我的猜测是他们不同,但我只想确定。
答案 0 :(得分:3)
虽然在谈到这两种机制时都使用了术语“信号”,但POSIX实时信号和pthread条件变量是不同的。
POSIX或操作信号是relatively rich semantics and history的“软件中断”。除SIG_IGN外,它们可能会被忽略(sa_sigaction),已发送( accepted ),blocked或when they can't be。他们可能有own stack用于用户定义的处置,尽管在处理过程中可以安全地进行处理is quite limited。他们可能会瞄准an individual thread或at 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