【问题标题】:How to resume a thread suspended by sigwaitinfo/sigwait? How to check for signal queue?如何恢复被 sigwaitinfo/sigwait 挂起的线程?如何检查信号队列?
【发布时间】:2016-10-29 16:53:14
【问题描述】:
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define NUM_THREADS 2

sem_t mutex;

pthread_t tid[NUM_THREADS];

void *thr_generator();
void *thr_handler();

int main(){
    sem_init(&mutex,0,1);   

    pthread_create(&tid[1],NULL,thr_handler,NULL);
    pthread_create(&tid[0],NULL,thr_generator,NULL);

    int i;
    for(i=0;i<2;i++){
        pthread_join(tid[i],NULL);
    }

    sem_destroy(&mutex);
}

void *thr_generator(){
    int i;
    for(i=0;i<10;i++){
        pthread_kill(tid[1],SIGUSR1);
        sleep(1);
    }
}

void *thr_handler(){
    sigset_t sig_set;
    sigemptyset(&sig_set);

    int i;
    int sig;
    sigaddset(&sig_set,SIGUSR1);
    pthread_sigmask(SIG_BLOCK,&sig_set,NULL);
    while(1){
        printf("Waiting on a signal...\n");



        if((i=(sigwaitinfo(&sig_set,NULL)))==10){
            printf("signal received\n");

        }
        else{
            printf("The set is empty\n");
            exit(0);
            //break;
        }


        printf("%d\n",i);

    }
    pthread_sigmask(SIG_UNBLOCK,&sig_set,NULL);

}

以上是我的整个测试代码供参考。

出于测试目的,我创建了 2 个线程,其中一个将 SIGUSR1 发送到另一个处理信号的线程。

我的问题是关于 thr_handler 函数。

当我编译并运行这段代码时,我会得到输出

Waiting on a signal...
signal received
.
.    (meaning the same output repeats x number of times according to the generator   loop)
.

Waiting on a signal...  (stuck here)

如果我的理解是正确的,thr_handler 中的 sigwaitinfo() 函数正在暂停处理线程,除非它接收到另一个信号,否则无法恢复线程。我该怎么做才能检查信号队列是否为空并跳出循环?有没有办法检查信号队列是否为空?

此外,最初,我计划在生成器循环的每次迭代中对 0.01 和 .1 之间的某个随机数使用 sleep()。这是否足够延迟,以便处理程序线程接收到所有信号?当我使用 10000 的生成器循环测试我的代码时,在我看来,处理程序根据输出只接收到大约 100 个或更少的信号。

【问题讨论】:

    标签: c multithreading signals


    【解决方案1】:

    在这部分代码中

    if((i=(sigwaitinfo(&sig_set,NULL)))==10){
                printf("signal received\n");
    
            }
    

    您应该检查正在发送的信号,SIGUSR1 所以它会是:

     if(sigwaitinfo(&sig_set,NULL) == SIGUSR1){
                    printf("signal received\n");
                }
    

    您已发送 10 个信号,因此将收到 10 个 SIGUSR1。 您只有一个线程运行安全的处理程序。但是,如果以后要生成多个线程来运行处理程序,则会出现同步问题,并且需要更多代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 2012-05-20
      • 2011-07-09
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多