如何恢复由sigwaitinfo / sigwait暂停的线程?如何检查信号队列?

时间:2016-10-29 16:53:15

标签: c multithreading signals

#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()函数正在挂起处理线程,除非收到另一个信号,否则无法恢复该线程。我该怎么做才能检查信号队列是否为空并突破循环?有没有办法检查信号队列是否为空?

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

1 个答案:

答案 0 :(得分:0)

在代码的这一部分

[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public string GetEmlpoyees() {
   Employee emps = new Employee[]{
      new Employee ()
      {
         // data...
      }
   };
   return emps;
}

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

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

        }

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