繁体   English   中英

如何停止正在运行的 pthread 线程?

[英]How to stop a running pthread thread?

如何立即退出或停止线程?

当用户输入答案时,如何使其立即停止? 我希望它为每个问题重置。

这是我的代码,其中涉及线程

int q1() {
    int timer_start;
    char ans[] = "lol";
    char user_ans[50];
    timer_start = pthread_create( &xtimer,NULL,(void*)timer_func,(void*)NULL);
    printf("What is the capital city of Peru?\n");

    while(limit){
        scanf("%s",user_ans);
        if(limit)
        {
             if(!strcmp(user_ans, ans))
              {

               // printf("YAY!\n");
                score++;
               // q2();

            }
            else
            {
                game_over();
            }
        }
    }
}

您可以简单地在该线程上调用pthread_cancel以退出它。 您可以通过pthread_kill发送 SIGSTOP/SIGCONT 信号来停止/重启它。


但是,如果您只想要一个计时器,为什么必须线程?

根据您的代码,我可以给出一个简单的答案:

在这种情况下,根本不要使用线程。

你不需要它们。 存储开始时间,让用户回答,用户回答后再次查看时间。

{
  time_t startTimeSec = time(NULL);

  // answering

  time_t endTimeSec = time(NULL);
  time_t timeTakenSec = endTime-startTime;
  if (timeTaken > 10) { 
    // do your thing
  }
}

回答你的问题:

您应该使用互斥保护或 volatile 变量在线程之间进行异步通信。 从一个线程设置该变量并在另一个线程中检查它。 然后重置其值并重复。 一个简单的片段:

int stopIssued = 0;
pthread_mutex_t stopMutex;

int getStopIssued(void) {
  int ret = 0;
  pthread_mutex_lock(&stopMutex);
  ret = stopIssued;
  pthread_mutex_unlock(&stopMutex);
  return ret;
}

void setStopIssued(int val) {
  pthread_mutex_lock(&stopMutex);
  stopIssued = val;
  pthread_mutex_unlock(&stopMutex);
}

使用pthread_cancel()是一种选择,但我不建议这样做。 您必须在此调用返回后检查线程状态,因为pthread_cancel()不会等待实际线程停止。 而且,对我来说更重要的是,我认为使用它很难看。

使用方法来停止线程是一种粗暴的方式。 您应该礼貌地要求线程通过发出信号来停止。 因此,线程将有一个选项来整理自己,例如,如果它已经分配了内存,如果线程被取消,它将没有任何机会这样做。

该方法相对简单,不包括操作系统信令:

在线程外部定义线程状态变量或结构。 在 pthread_create 处指向它并取消引用线程中的状态变量。

int thread_state = 0; // 0: normal, -1: stop thread, 1: do something

static void *thread_1 (void *arg)
{
   int* pthread_state = arg;
   ... // initialize the thread locals
   while(1)
   {
      switch( *pthread_state )
      {
      case 0: // normal thread loop
         ...
         break;
      case -1:
         ... // tidy or whatever is necessary
         pthread_exit(0); // exit the thread signalling normal return
         break;
      case 1: //
         ... // do something special
         break;
      }
   }
}

pthread_create (&t_1, NULL, thread_1, (void*)&thread_state);

...

thread_state = -1; // signal to the thread to stop

// maybe use pthread_exit(0) to exit main.
// this will leave the threads running until they have finished tidy etc.

甚至可以使用结构与线程进行通信,前提是它是简单的“原子”变量或建立了简单的握手机制。 否则可能需要使用互斥锁。 使用 pthread_join 等待线程终止。

@Naruil 建议调用pthread_cancel()几乎是我找到的最佳解决方案,但如果您不执行以下操作,它将无法工作。

根据pthread_cancel手册页, pthread_cancelibility 取决于两件事

  1. 线程取消状态。
  2. 线程取消类型。

thread_cancel_state默认是PTHREAD_CANCEL_ENABLE ,所以我们主要关心的是thread_cancel_type ,它的默认值是类型PTHREAD_CANCEL_DEFFERED但我们需要在该线程上设置PTHREAD_CANCEL_ASYNCHRONOUS ,我们不想取消。

下面给出一个例子:

#include <stdio.h>
#include <pthread.h>

void *thread_runner(void* arg)
{   
    //catch the pthread_object as argument
    pthread_t obj = *((pthread_t*)arg);

    //ENABLING THE CANCEL FUNCTIONALITY
    int prevType;
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &prevType);

    int i=0;
    for( ; i < 11 ; i++)//1 - > 10
    {
        if(i == 5)
            pthread_cancel(obj);
        else
            printf("count -- %d", i);
    }
    printf("done");
}

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

    pthread_create(&obj, NULL, thread_runner, (void*)&obj);

    pthread_join(obj, NULL);

    return 0;
}

使用gcc filename.c -lpthread运行它并输出以下内容: count -- 0 count -- 1 count -- 2 count -- 3 count -- 4

请注意, done永远不会打印,因为当 i 变为 5 并且正在运行的线程被取消时线程被取消。 特别感谢@Naruil 的“pthread_cancel”建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM