POSIX 線程 – pthread_sigmask
概念
- 按照 POSIX, 異步 (外部) 信號(hào)發(fā)送到整個(gè)進(jìn)程.
- 所有線程共享同一個(gè)設(shè)置, 即通過(guò) sigaction 設(shè)置的線程處置方法.
- 每個(gè)線程有自己的信號(hào)掩碼, 線程庫(kù)根據(jù)該掩碼決定將信號(hào)發(fā)送到哪個(gè)線程.
- 由于 Linux 線程實(shí)現(xiàn)上的獨(dú)特性, 外部信號(hào)始終發(fā)送到特定的線程.
pthread_sigmask
- pthread_sigmask 用來(lái)定義線程的信號(hào)掩碼
- 其接口與 sigprocmask 一樣
===============================================================================
#include <pthread.h>
#include <signal.h>
int pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask);
===============================================================================
pthread_kill 和 sigwait
===============================================================================
#include <pthread.h>
#include <signal.h>
int pthread_kill (pthread_t thread, int signo);
int sigwait (const sigset_t *set, int *sig);
===============================================================================
- pthread_kill 向特定的線程發(fā)送信號(hào).
- sigwait 暫定調(diào)用線程, 直到 set 中定義的某個(gè)信號(hào)遞達(dá)調(diào)用線程.
- sigwait 返回時(shí), sig 中保存的是接收到的信號(hào)編號(hào).
- sigwait 所等待的信號(hào)必須在所有線程中阻塞, 而不僅僅是調(diào)用線程.
在多線程的程序里,希望只在主線程中處理信號(hào),可以使用
函數(shù):
int pthread_sigmask (int how,
const sigset_t *set,
sigset_t *oset)
用作在主調(diào)線程里控制信號(hào)掩碼。
How:
SIG_BLOCK: 結(jié)果集是當(dāng)前集合參數(shù)集的并集
SIG_UNBLOCK: 結(jié)果集是當(dāng)前集合參數(shù)集的差集
SIG_SETMASK: 結(jié)果集是由參數(shù)集指向的集
頭文件: <signal.h>
錯(cuò)誤: [EINVAL] how不是已定義值
提示: 除非信號(hào)在所有的線程里都阻塞,否則總能將異步信號(hào)傳輸給這個(gè)進(jìn)程。
例子:
#include <pthread.h>
#include <stdio.h>
#include <sys/signal.h>
#define NUMTHREADS 3
void sighand(int signo);
void *threadfunc(void *parm)
{
pthread_t tid = pthread_self();
int rc;
printf("Thread %u entered\n", tid);
rc = sleep(30);
printf("Thread %u did not get expected results! rc=%d\n", tid, rc);
return NULL;
}
void *threadmasked(void *parm)
{
pthread_t tid = pthread_self();
sigset_t mask;
int rc;
printf("Masked thread %lu entered\n", tid);
sigfillset(&mask); /* Mask all allowed signals */
rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (rc != 0)
{
printf("%d, %s\n", rc, strerror(rc));
return NULL;
}
rc = sleep(15);
if (rc != 0)
{
printf("Masked thread %lu did not get expected results! "
"rc=%d \n", tid, rc);
return NULL;
}
printf("Masked thread %lu completed masked work\n",
tid);
return NULL;
}
int main(int argc, char **argv)
{
int rc;
int i;
struct sigaction actions;
pthread_t threads[NUMTHREADS];
pthread_t maskedthreads[NUMTHREADS];
printf("Enter Testcase - %s\n", argv[0]);
printf("Set up the alarm handler for the process\n");
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = sighand;
rc = sigaction(SIGALRM,&actions,NULL);
printf("Create masked and unmasked threads\n");
for(i=0; i<NUMTHREADS; ++i)
{
rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
if (rc != 0)
{
printf("%d, %s\n", rc, strerror(rc));
return -1;
}
rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
if (rc != 0)
{
printf("%d, %s\n", rc, strerror(rc));
return -1;
}
}
sleep(3);
printf("Send a signal to masked and unmasked threads\n");
for(i=0; i<NUMTHREADS; ++i)
{
rc = pthread_kill(threads[i], SIGALRM);
rc = pthread_kill(maskedthreads[i], SIGALRM);
}
printf("Wait for masked and unmasked threads to complete\n");
for(i=0; i<NUMTHREADS; ++i) {
rc = pthread_join(threads[i], NULL);
rc = pthread_join(maskedthreads[i], NULL);
}
printf("Main completed\n");
return 0;
}
void sighand(int signo)
{
pthread_t tid = pthread_self();
printf("Thread %lu in signal handler\n",
tid);
return;
}
程序返回:
Enter Testcase - ./pthread_sigmask_test
Set up the alarm handler for the process
Create masked and unmasked threads
Thread 3086597040 entered
Masked thread 3076107184 entered
Thread 3065617328 entered
Masked thread 3055127472 entered
Thread 3044637616 entered
Masked thread 3034147760 entered
Send a signal to masked and unmasked threads
Wait for masked and unmasked threads to complete
Thread 3086597040 in signal handler
Thread 3086597040 did not get expected results! rc=27
Thread 3065617328 in signal handler
Thread 3065617328 did not get expected results! rc=27
Thread 3044637616 in signal handler
Thread 3044637616 did not get expected results! rc=27
Masked thread 3076107184 completed masked work
Masked thread 3055127472 completed masked work
Masked thread 3034147760 completed masked work
Main completed