執行緒與訊號 -- pthread_sigmask() sigwait()
阿新 • • 發佈:2018-11-08
一、主執行緒傳送USR1訊號給子執行緒1 ,子執行緒中新增 訊號捕捉,子執行緒2沒有捕捉訊號,導致直接退出
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #define handle_error_en(en, msg) \ do {errno = en; perror(msg); exit(EXIT_FAILURE); }while(0) static void *sig_thread1(void *arg) { sigset_t *set = (sigset_t *)arg; int ret, sig; sigaddset(set, SIGUSR1); pthread_sigmask(SIG_SETMASK, set, NULL); for (;;) { // 等待被遮蔽的訊號 SIGQUIT printf("before sigwait1..\n"); ret = sigwait(set, &sig); if (ret != 0) handle_error_en(ret, "thread2 sigwait"); printf("Signal handling thread1 got signal %d\n", sig); } } static void *sig_thread2(void *arg) { sigset_t set; sigemptyset(&set); int ret, sig; for (;;) { // thread2 沒有設定捕捉任何訊號, // 除SIGQUIT被遮蔽,其餘訊號均可導致執行緒退出 printf("before sigwait2..\n"); ret = sigwait(&set, &sig); if (ret != 0) handle_error_en(ret, "thread2 sigwait"); printf("Signal handling thread2 got signal %d\n", sig); } } int main(int argc, const char *argv[]) { pthread_t thread1; pthread_t thread2; sigset_t set; int ret; sigemptyset(&set); sigaddset(&set, SIGQUIT); // SIG_BLOCK 遮蔽 SIG_UNBLOCK 解遮蔽 SIG_SETMASK 設定 ret = pthread_sigmask(SIG_BLOCK, &set, NULL); if (ret!=0 ) handle_error_en(ret, "pthread_sigmask"); ret = pthread_create(&thread1, NULL, sig_thread1, &set); ret = pthread_create(&thread2, NULL, sig_thread2, NULL); sleep(2); pthread_kill(thread1, SIGUSR1); printf("kill thread1 SIGUSR1.\n"); sleep(2); pthread_kill(thread2, SIGUSR1); printf("kill thread2 SIGUSR1.\n"); pause(); return 0; }
二、 執行緒1 捕捉被遮蔽訊號,執行緒2沒有捕捉
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #define handle_error_en(en, msg) \ do {errno = en; perror(msg); exit(EXIT_FAILURE); }while(0) static void *sig_thread1(void *arg) { sigset_t *set = (sigset_t *)arg; int ret, sig; for (;;) { // 等待被遮蔽的訊號 SIGQUIT printf("before sigwait1..\n"); ret = sigwait(set, &sig); if (ret != 0) handle_error_en(ret, "thread2 sigwait"); printf("Signal handling thread1 got signal %d\n", sig); } } static void *sig_thread2(void *arg) { sigset_t set; sigemptyset(&set); int ret, sig; for (;;) { // thread2 沒有設定捕捉任何訊號, // 除SIGQUIT被遮蔽,其餘訊號均可導致執行緒退出 printf("before sigwait2..\n"); ret = sigwait(&set, &sig); if (ret != 0) handle_error_en(ret, "thread2 sigwait"); printf("Signal handling thread2 got signal %d\n", sig); } } int main(int argc, const char *argv[]) { pthread_t thread1; pthread_t thread2; sigset_t set; int ret; sigemptyset(&set); sigaddset(&set, SIGQUIT); // SIG_BLOCK 遮蔽 SIG_UNBLOCK 解遮蔽 SIG_SETMASK 設定 ret = pthread_sigmask(SIG_BLOCK, &set, NULL); if (ret!=0 ) handle_error_en(ret, "pthread_sigmask"); ret = pthread_create(&thread1, NULL, sig_thread1, &set); ret = pthread_create(&thread2, NULL, sig_thread2, NULL); sleep(2); pthread_kill(thread1, SIGQUIT); printf("kill thread1 SIGQUIT.\n"); sleep(2); pthread_kill(thread2, SIGQUIT); printf("kill thread2 SIGQUIT.\n"); pause(); return 0; }