如何退出信号量暂停的线程?

时间:2017-11-15 20:53:41

标签: c multithreading

在main函数中,我创建了一个生成器线程和两个消费者线程。 制作人做了一些工作,然后用"如果"语句检查是否应该中断然后增加信号量。消费者正在等待信号量变得大于0并做一些工作,然后再等待。当生产者退出时,消费者应该完成他们的工作并退出。我不明白如何退出由信号量暂停的线程?这是我的代码:

sem_t ready;

void *prod_routine(void*){
    while(true){
        //do_something
        //here i have if statement with break.
        sem_post(&ready);
    }   
pthread_exit(0);
}

void *cons_routine(void*){
    while(true){
        sem_wait(&ready);
        //do something
    }
pthread_exit(0);
}

int main(int argc, char *argv[]){

pthread_t prod, cons1, cons2;

sem_init(&ready, 0 , 0);

pthread_create(&prod, NULL, &prod_routine, NULL);
pthread_create(&cons1, NULL, &cons_routine, NULL);
pthread_create(&cons2, NULL, &cons_routine, NULL);

pthread_join(prod, NULL);
pthread_join(cons1, NULL);
pthread_join(cons2, NULL);

return 0;
}

2 个答案:

答案 0 :(得分:1)

  

我不明白如何退出被信号量暂停的线程?

从字面意义上讲,你不能。挂起等待获取信号量的线程无法执行任何,直到它停止等待,包括终止。那么,主要的问题是如何让这些线程停止等待。

至少有四种方法可以实现这一目标:

  • 增加信号量,以便线程可以获取它。这是最干净,最好的方法。诀窍是提供一种机制,线程在唤醒时可以识别它应该终止而不是正常进行。

  • 使用sem_timedwait()代替sem_wait(),并等待超时到期。这有点狡猾,因为尽管你可以确定sem_timedwait()是否因为超时而返回,但它不一定清楚线程应该做些什么。

  • 使用pthread_cancel()向线程发送取消请求。这个sem_wait()中阻止的线程有效,但它相当严厉。特别是,它启动的事件链或多或少直接导致线程终止。

  • 通过pthread_kill()向线程发送信号。但是,请注意,信号处理是整个过程的。特别是,如果所选信号的处置是"停止"或者"终止" (并且它没有被阻止)那么这将影响整个过程。这依赖于未使用SA_RESTART标志配置的信号。

除了pthread_cancel()之外,所有这些都有一个共同点,即等待信号量的线程需要检查它何时返回它等待为什么返回。它必须检查sem_[timed]wait()的返回值以及可能errno的值,并且可能需要检查一个或多个有目的的共享变量。

答案 1 :(得分:0)

首先尝试使用pthread_kill()。对于第一次调用pthread_cancel,然后是pthread_kill(),信号为SIGSTOP。即使在那之后,你试图用sem_destroy()破坏信号量也不起作用。