- 论坛徽章:
- 11
|
虽然是学习,严谨一些更好,以免在生产环境出事,LZ例子问题太多,请容我逐一列举,随之问题的原因和解决办法就很显然了:
1. 用严格的编译选项。我是CentOS 6.4,和你的环境是非常相似,用gcc的"-Wall"有警告。
2. 对于某个函数的用法,先看man再用。你的例子中,pthread_sigmask和sigwait非常关键,恰好man为pthread_sigmask提供了一个例子,很好的说明了sigwait的用法精髓。
3. sigwait的真正意义。信号和多线程一直是UNIX/LINUX下的大坑所在,两者合为一处更是坑中之坑,一定要遵循被总结出的良好实践。sigwait和pthead_sigmask相互配合,可以让异步的信号处理转化为单独一个线程的同步行为,大为简化实现,比如传统信号处理函数中必须使用可重入函数,但LZ所用的printf却不可重入,不过正确使用sigwait后,就可以不管这类烦恼的问题。
4. LZ例子不符合sigwait基本用法(如创建子线程前,先将待处理的信号block),先按照下面man提供的例子修改下代码,这就是多线程信号的推荐处理逻辑。- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <errno.h>
- /* Simple error handling functions */
- #define handle_error_en(en, msg) \
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
- static void *
- sig_thread(void *arg)
- {
- sigset_t *set = (sigset_t *) arg;
- int s, sig;
- for (;;) {
- s = sigwait(set, &sig);
- if (s != 0)
- handle_error_en(s, "sigwait");
- printf("Signal handling thread got signal %d\n", sig);
- }
- }
- int
- main(int argc, char *argv[])
- {
- pthread_t thread;
- sigset_t set;
- int s;
- /* Block SIGINT; other threads created by main() will inherit
- a copy of the signal mask. */
- sigemptyset(&set);
- sigaddset(&set, SIGQUIT);
- sigaddset(&set, SIGUSR1);
- s = pthread_sigmask(SIG_BLOCK, &set, NULL);
- if (s != 0)
- handle_error_en(s, "pthread_sigmask");
- s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
- if (s != 0)
- handle_error_en(s, "pthread_create");
- /* Main thread carries on to create other threads and/or do
- other work */
- pause(); /* Dummy pause so we can test program */
- }
复制代码 |
|