通过一个简单的例子,总结一下pthread中信号量的使用方式以及使用pthread_detach和使用pthread_join的区别。以备以后查阅。
涉及到的函数:
int pthread_kill(pthread_t thread, int sig) :向线程发送一个信号,参数分别为线程ID和信号量。在线程内部可以对信号进行处理,当然也有一些系统默认的出来方式。比如发送信号SIGQUIT,该线程则会退出。
sigemptyset: 初始化信号量并清空。
sigaddset:把信号加入信号集,这样在等待信号量时,也可以等待一个信号量的集合中的某一个信号。
int sigwait(const sigset_t *set, int *sig):等待信号集,并返回接收到的信号量。
pthread_detach(pthread_t thread):如果线程调用了该函数,主进程不会被阻塞等待线程结束才返回,而是启动了线程后去继续自己的工作。这是它与pthread_join()不同的地方。
实例程序 1 (使用 pthread_join)
#include <signal.h> #include <errno.h> #include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> void sig_handler(int signum) { printf("Receive signal. %d\n", signum); } void* sigmgr_thread(void* p) { sigset_t waitset, oset; int sig; int rc; pthread_t ppid = pthread_self(); //pthread_detach(ppid); sigemptyset(&waitset); sigaddset(&waitset, SIGRTMIN); sigaddset(&waitset, SIGRTMIN+2); sigaddset(&waitset, SIGRTMAX); sigaddset(&waitset, SIGUSR1); sigaddset(&waitset, SIGUSR2); while (1) { sleep(1); printf("thread is alive...\n"); rc = sigwait(&waitset, &sig); if (rc != -1) { sig_handler(sig); } else { printf("sigwaitinfo() returned err: %d \n", errno); } } } int main() { sigset_t bset, oset; int i; printf("main { \n"); pthread_t ppid; sigemptyset(&bset); sigaddset(&bset, SIGRTMIN); sigaddset(&bset, SIGRTMIN+2); sigaddset(&bset, SIGRTMAX); sigaddset(&bset, SIGUSR1); sigaddset(&bset, SIGUSR2); printf("main pthread_sigmask \n"); if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0) printf("!! Set pthread mask failed\n"); printf("main create thread\n"); // Create the dedicated thread sigmgr_thread() which will handle signals synchronously pthread_create(&ppid, NULL, sigmgr_thread, NULL); printf("main start send signal \n"); pthread_kill(ppid, SIGRTMAX); pthread_kill(ppid, SIGRTMAX); pthread_kill(ppid, SIGRTMIN+2); pthread_kill(ppid, SIGRTMIN); pthread_kill(ppid, SIGRTMIN+2); pthread_kill(ppid, SIGRTMIN); pthread_kill(ppid, SIGUSR2); pthread_kill(ppid, SIGUSR2); pthread_kill(ppid, SIGUSR1); pthread_kill(ppid, SIGUSR1); printf("main sleep 20 seconds/n"); sleep(20); pthread_join(ppid, NULL); printf("main }\n"); return 0; }
实例程序 2 (使用 pthread_detach)
#include <signal.h> #include <errno.h> #include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> void sig_handler(int signum) { printf("Receive signal. %d\n", signum); } void* sigmgr_thread(void* p) { sigset_t waitset, oset; int sig; int rc; pthread_t ppid = pthread_self(); pthread_detach(ppid); sigemptyset(&waitset); sigaddset(&waitset, SIGRTMIN); sigaddset(&waitset, SIGRTMIN+2); sigaddset(&waitset, SIGRTMAX); sigaddset(&waitset, SIGUSR1); sigaddset(&waitset, SIGUSR2); while (1) { sleep(1); printf("thread is alive...\n"); rc = sigwait(&waitset, &sig); if (rc != -1) { sig_handler(sig); } else { printf("sigwaitinfo() returned err: %d \n", errno); } } } int main() { sigset_t bset, oset; int i; printf("main { \n"); pthread_t ppid; sigemptyset(&bset); sigaddset(&bset, SIGRTMIN); sigaddset(&bset, SIGRTMIN+2); sigaddset(&bset, SIGRTMAX); sigaddset(&bset, SIGUSR1); sigaddset(&bset, SIGUSR2); printf("main pthread_sigmask \n"); if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0) printf("!! Set pthread mask failed\n"); printf("main create thread\n"); // Create the dedicated thread sigmgr_thread() which will handle signals synchronously pthread_create(&ppid, NULL, sigmgr_thread, NULL); printf("main start send signal \n"); pthread_kill(ppid, SIGRTMAX); pthread_kill(ppid, SIGRTMAX); pthread_kill(ppid, SIGRTMIN+2); pthread_kill(ppid, SIGRTMIN); pthread_kill(ppid, SIGRTMIN+2); pthread_kill(ppid, SIGRTMIN); pthread_kill(ppid, SIGUSR2); pthread_kill(ppid, SIGUSR2); pthread_kill(ppid, SIGUSR1); pthread_kill(ppid, SIGUSR1); printf("main sleep 20 seconds/n"); sleep(20); //pthread_join(ppid, NULL); printf("main }\n"); return 0; }