signal handling in thread

线程中的信号处理比进程中信号处理更复杂。APUE中建议使用一个单独的进程来同步的处理(等待)信号的到来,而其他的线程则block所有的信号。

 

下面这是一个简单的例子。

需要注意的是:

使用sigwait前,需要先block想要等待的信号,否则会产生窗口,而丢失信号。

书上是这么说的,我觉得block信号是要在sigwait用在循环里时才需要的。

这点应该和sigsuspend是一样的。

 

#include <apue.h>
#include <pthread.h>

int         quitflag = 0;
sigset_t    mask;

pthread_mutex_t  lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t   wait = PTHREAD_COND_INITIALIZER;

void*
thr_fn(void *arg)
{
    int err, signo;

    for (;;)
    {
        err = sigwait(&mask, &signo);
        if (err != 0)
            err_exit(err, "sigwait failed");
        switch (signo)
        {
            case SIGINT:
                printf("/ninterrupt/n");
                break;

            case SIGQUIT:
                pthread_mutex_lock(&lock);
                quitflag = 1;
                pthread_mutex_unlock(&lock);
                pthread_cond_signal(&wait);
                return(0);

            default:
                printf("unexpected signal %d/n", signo);
                exit(1);
        }
    }
}

int
main ()
{
    int       err;
    sigset_t  oldmask;
    pthread_t tid;

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);
    if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
        err_exit(err, "SIG_BLOCK error");

    err = pthread_create(&tid, NULL, thr_fn, 0);
    if (err != 0)
        err_exit(err, "can't create thread");
   
    pthread_mutex_lock(&lock);
    while (quitflag == 0)
        pthread_cond_wait(&wait, &lock);
    pthread_mutex_unlock(&lock);

    /* SIGQUIT has been caught and is now blocked; do whatever */
    quitflag = 0;

    /* reset signal mask which unblocks SIGQUIT */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");

    exit(0);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是因为在非主线程中使用了信号(signal)。在Python中,信号(signal)只能在主线程中使用,如果在其他线程中使用,就会出现这个错误。要解决这个问题,可以将信号处理程序放在主线程中,或者使用线程安全的信号处理方式。 ### 回答2: valueerror: signal only works in main thread信号仅在主线程中工作)是一个Python编程中常见的错误信息,通常出现在多线程编程中。 多线程编程是指创建多个线程,在不同的线程中同时运行不同的代码。这种编程方式可以提高程序的性能和效率,但也带来了线程安全问题。在多线程编程中,如果子线程想要修改主线程的某些属性或执行某些操作,就需要使用信号(signal)来通知主线程。 在Python中,信号(signal)是一种线程间通信的方式。主线程可以在接收到信号后,执行与信号绑定的回调函数,实现对子线程的控制。但是,Python的信号(signal)只能在主线程中接收和处理,如果在子线程中创建信号(signal),就会出现valueerror: signal only works in main thread信号只在主线程中有效)的错误信息。 原因是Python的信号(signal)是基于操作系统提供的信号机制实现的,而不同的操作系统实现信号机制的方式不同。为了确保线程安全,Python规定只有主线程才能接收和处理信号(signal)。因此,在多线程编程中,在子线程中创建和处理信号(signal)是不可行的。 要解决这个错误,可以通过在主线程中创建信号(signal),并将信号与子线程绑定,让子线程触发信号(signal),从而实现主线程对子线程的控制。另外,还可以使用Python的Queue模块来实现线程间的通信,避免在子线程中创建信号(signal)。 ### 回答3: 这个错误通常会在Python多线程编程中出现。简单地说,该错误是由于尝试在非主线程中使用signal模块引起的。signal模块在Python中用于处理UNIX信号,它允许我们在程序接收到UNIX信号时执行特定的操作。但是,signal模块只能在主线程中使用,这意味着我们必须将信号处理程序放在主线程中,否则就会遇到“valueerror: signal only works in main thread”的错误。 为了解决这个问题,我们需要signal模块中的信号处理程序封装到一个函数中,然后在主线程中调用这个函数。例如,我们可以使用Python的threading模块来创建多个线程,但必须将信号处理程序放在主线程中。下面是一个示例代码: ``` import signal import threading def signal_handler(sig, frame): print('Signal received: {}'.format(sig)) def main(): signal.signal(signal.SIGINT, signal_handler) thread = threading.Thread(target=worker) thread.start() def worker(): while True: pass if __name__ == '__main__': main() ``` 在这个例子中,我们在主线程中注册了SIGINT信号的处理程序,该程序在程序接收到SIGINT信号时打印一条消息。我们还创建了一个worker线程并启动它。由于SIGINT信号处理程序在主线程中注册,因此它仅在程序接收到信号时被调用,而不是在worker线程中无限循环期间被调用。 总之,我们需要注意的是,signal模块只能在主线程中使用,不能在其他线程中使用。因此,在多线程编程中,我们应该将信号处理程序放在主线程中,并在必要时使用线程间通信机制进行通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值