pthread 条件信号与 POSIX 实时信号相同还是不同?
Are pthread condition signals the same or different from POSIX real-time signals?
我正在学习 OS class 中的 pthreads 和信号,我有一个问题:pthread_cond_signal
的底层信号机制只是一个标准的 POSIX实时信号,已经适合唤醒等待线程的任务了?或者是其他机制碰巧使用相同的术语来描述两种不同的想法?
如果它们相同,我应该可以使用 pthread_kill
告诉线程从 pthread_cond_wait
唤醒,对吗?我能否以某种方式更改线程的信号掩码,以便它在应该接收来自 pthread_cond_signal
的信号时不接收信号?我意识到这些是糟糕的编码实践和一些 hack-y 尝试的事情,但我只想了解 pthread wait/signal 进程的底层机制。
我尝试阅读算法 here,但它让我有些不知所措。我的猜测是它们是不同的,但我只是想确定一下。
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
虽然在谈到这两种机制时使用了术语 "signal",但 POSIX 实时信号和 pthread 条件变量是不同的。
POSIX或操作信号为"software interrupts"和relatively rich semantics and history. They may be ignored (SIG_IGN), delivered (sa_sigaction), accepted, or blocked, except when they can't be. They may have their own stack for user-defined disposal, though what one can safely do during disposal . They might take aim at an individual thread or at a whole process. They interrupt some functions, but not others, sometimes at the end-user's discretion (SA_RESTART). Realtime extensions allow signals to queue and perhaps deliver a word of data。还有更多。
相比之下,POSIX pthread 条件变量 synchronization mechanisms 保护某些谓词。这里,"signal" 是唤醒一个等待条件变量的线程的 user-initiated 操作,如果存在这样一个线程。
当我们谈论这些机制时,同一个术语在不同的意义上使用可能很不幸,但事实就是如此。
我正在学习 OS class 中的 pthreads 和信号,我有一个问题:pthread_cond_signal
的底层信号机制只是一个标准的 POSIX实时信号,已经适合唤醒等待线程的任务了?或者是其他机制碰巧使用相同的术语来描述两种不同的想法?
如果它们相同,我应该可以使用 pthread_kill
告诉线程从 pthread_cond_wait
唤醒,对吗?我能否以某种方式更改线程的信号掩码,以便它在应该接收来自 pthread_cond_signal
的信号时不接收信号?我意识到这些是糟糕的编码实践和一些 hack-y 尝试的事情,但我只想了解 pthread wait/signal 进程的底层机制。
我尝试阅读算法 here,但它让我有些不知所措。我的猜测是它们是不同的,但我只是想确定一下。
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
虽然在谈到这两种机制时使用了术语 "signal",但 POSIX 实时信号和 pthread 条件变量是不同的。
POSIX或操作信号为"software interrupts"和relatively rich semantics and history. They may be ignored (SIG_IGN), delivered (sa_sigaction), accepted, or blocked, except when they can't be. They may have their own stack for user-defined disposal, though what one can safely do during disposal
相比之下,POSIX pthread 条件变量 synchronization mechanisms 保护某些谓词。这里,"signal" 是唤醒一个等待条件变量的线程的 user-initiated 操作,如果存在这样一个线程。
当我们谈论这些机制时,同一个术语在不同的意义上使用可能很不幸,但事实就是如此。