使用延迟取消结束pthreads

时间:2016-04-03 22:40:52

标签: c multithreading pthreads signals mutex

我是pthreads和信号处理的新手,我正在开发一个项目,它将创建x数量的pthread作为生产者或消费者,永远执行,我想结束所有线程然后是系统的主要方式。

为此,我试图用信号处理程序捕获^c,然后设置一些全局标志然后结束线程。

我尝试过以下操作,但我不确定它是否有效,我想就我的思维过程和实施提出建议。

以下是我正在使用的内容,省略错误检查:

#include stdio, pthread, stdlib, semaphore, time, string, unistd, signal

sem_t empty, full;
pthread_mutex_t mutex;
int flag = 0;
void *producer();
void *consumer();
void sig_handler(int sig);

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

   signal(handler(SIGINT, sig_handler);

   //init locks and semas
   pthread_mutex_init(&mutex, NULL);
   sem_init(&empty, 0, SOME_BUFFER_SIZE);
   sem_init(&full, 0, 0);

   pthread_t prod_threads[5]; //5 for example, can be any amount passed in
   pthread_t cons_threads[3];

   //start up threads
   for(i = 0; i < 5; i++)
      pthread_create(&prod_threads[i], NULL, producer, NULL)
   for(i = 0; i < 3; i++)
      pthread_create(&cons_threads[i], NULL, consumer, NULL)

   //join threads at end
   for(i = 0; i < PROD; i++)
     pthread_join(&prod_threads[i], NULL);

   for(i = 0; i < CONS; i++)
     pthread_join(&cons_threads[i], NULL);

   sleep(4);//could be any amount of time
   exit(EXIT_SUCCESS);

}
//not sure if I am going about this the right way
void sig_handler(int sig){
  if(sig == SIGINT)
    flag = 1;

}

void *producer(){
  while(1){
    sleep(x);//where x is some random time

    //part I am concerned about:
     if(flag)
      exit(EXIT_SUCCESS);
    //get locks and semaphore stuff
    //enter crit section
    //release locks, semaphore
  }
 void *consumer(){
   while(1){
      sleep(x);//sleep some random time

      //again not sure if this is right or not
      if(flag)
        exit(EXIT_SUCCESS);
      //get locks
      //enter crit
      //release locks
  }



 }
}

我的程序似乎正常执行,我只是不确定我是否正确使用pthreads和信号,并希望在那里有一些指导。如果您需要更完整的代码,请告诉我

由于

2 个答案:

答案 0 :(得分:0)

您的执行似乎是合适的,但是如果使用提供的文档@yano,您pthread_join()的关注度会非常低。

而不是:

for(i = 0; i < PROD; i++)
 pthread_join(&prod_threads[i], NULL);

for(i = 0; i < CONS; i++)
 pthread_join(&cons_threads[i], NULL);

你需要:

for(i = 0; i < PROD; i++)
 pthread_join(prod_threads[i], NULL);

for(i = 0; i < CONS; i++)
 pthread_join(cons_threads[i], NULL);

注意&符号。无论这是否是您正在寻找的,我不确定,但我希望它有所帮助。

答案 1 :(得分:0)

I want to end all threads and then the main in a systematic way.

As Martin James suggests, post a special thread message into the queue telling the worker threads to terminate. This message should not be removed from the queue, so that all worker threads have a chance to receive it and terminate.

The other point is that you should not call exit in your worker threads, since this function terminates the entire process, defeating your original goal. Just return from the thread function.

Another point is that in a multi-threaded application it is good practice to handle all signals in one specific thread (often the main thread is the best candidate for that). And block the signals you expect to receive in all other threads. It should be done by blocking the expected signals before creating other threads, so that they inherit the signal mask, and eventually unblocking these signals in the signal handling thread when it is ready to handle them (e.g. when all extra threads have been created). This is because a signal targeted for a process (such as SIGINT) can be delivered to any one of its threads, but we want it to be handled by one specific thread. See Signal Generation and Delivery for more details.