免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1072 | 回复: 0
打印 上一主题 下一主题

some notes on pthreads & signals [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-17 14:25 |只看该作者 |倒序浏览
- Signals are delivered to process wide instead of thread wide, a process group (may include many threads) only have a single signal handler (sigaction), but each thread may have their own signal mask
- A thread's signal mask is inherited from it's creator.
- A thread could alter its signal mask by calling pthread_sigmask(), even though sigprocmask() is almost indentical under Linux, but we should prefer pthread_sigmask(), since it's explicitly documented in POSIX 2001 for multithreaded environment.
- Based on the above notes, when many threads are waiting a (specific) signal (by using pause(), sigwait() or sigwaitinfo()), and when the signal is raised, the signal is only delivered to one (and only one) thread; the signal will caused the signal handler (setuped by sigaction) to be called, and then the blocked (the only) thread (wait for signal) is resumed. After the signal is processed, the signal will NOT be propagated among threads.
- We could deliver thread wide signal by using pthread_kill().
- Please Don't use sleep() or usleep() in threads, use nanosleep() instead, the former might be depends on signals (SIGALARM), but the latter is safe. (usleep will be deprecated in POSIX 2008)
For more details, please see related man pages, specifically ``man 3 pthread_sigmask'', which also shows a example of pthread with signals.
here is a dumb example showing pthread & signals (mask), compile it with: ``gcc -O2 sig-test2.c -o sig-test2 -Wall -lpthread'', run the program in one terminal, and then switch to another terminal, use ``pkill -USR1 sig-test2'' to test the program.
/* sig-test2.c */
#include sys/types.h>
#include signal.h>
#include pthread.h>
#include time.h>
#include unistd.h>
#include stdlib.h>
#include string.h>
#include stdio.h>
static pthread_t thread_ids[2];
static void my_sig_handler(int sig, siginfo_t* pi, void* ucontext)
{
        fprintf(stderr, "got signal: %d\n", pi->si_signo);
}
static void sig_set_handler(void)
{
        struct sigaction new, old;
        memset(&new, 0, sizeof(new));
        new.sa_sigaction = my_sig_handler;
        // new.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER;
        new.sa_flags = SA_SIGINFO | SA_NODEFER;
        if (sigaction(SIGUSR1, &new, &old)  0) {
                fprintf(stderr, "unable to set handler!\n");
                exit(1);
        }
}
static void sig_block_all(void)
{
        sigset_t new;
        sigfillset(&new);
        pthread_sigmask(SIG_BLOCK, &new, NULL);
}
static void* thread_fn(void* param)
{
        sigset_t new;
        int sig;
        long id = (long)param;
#if 1
        sigemptyset(&new);
        sigaddset(&new, SIGUSR1);
        sigwait(&new, &sig);
#else
        sigemptyset(&new);
        sigaddset(&new, SIGUSR1);
        pthread_sigmask(SIG_UNBLOCK, &new, NULL);
        pause();
#endif
        printf("%lu restore from pause, signal: %d.\n", id, sig);
        return (void*)0;
}
int main(int argc, char* argv[])
{
        pthread_t tid;
        long i;
        sig_block_all();
        sig_set_handler();
        for (i = 0; i  2; i++) {
                if (pthread_create(&thread_ids, NULL, thread_fn, (void*)i)  0) {
                        fprintf(stderr, "pthread_create: \n");
                        exit(1);
                }
        }
        sleep(1);
        for (i = 0; i  2; i++) {
                pthread_join(thread_ids, NULL);
        }
        return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/98727/showart_2123864.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP