简体   繁体   English

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

[英]How to stop a running pthread thread?

How can I exit or stop a thread immediately?如何立即退出或停止线程?

How can I make it stop immediately when the user enters an answer?当用户输入答案时,如何使其立即停止? I want it to reset for every question.我希望它为每个问题重置。

Here's my code where threading is involved这是我的代码,其中涉及线程

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();
            }
        }
    }
}

You can simply call pthread_cancel on that thread to exit it.您可以简单地在该线程上调用pthread_cancel以退出它。 And you can send SIGSTOP/SIGCONT signal via pthread_kill to stop/restart it.您可以通过pthread_kill发送 SIGSTOP/SIGCONT 信号来停止/重启它。


But if all you want is a timer, why must you thread?但是,如果您只想要一个计时器,为什么必须线程?

Based on your code I can give a simple answer:根据您的代码,我可以给出一个简单的答案:

In this case do not use threads at all.在这种情况下,根本不要使用线程。

You do not need them.你不需要它们。 Store the start time, let the user answer, check the time again after user gives an answer.存储开始时间,让用户回答,用户回答后再次查看时间。

{
  time_t startTimeSec = time(NULL);

  // answering

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

To answer your question:回答你的问题:

You should use a mutex-protected or volatile variable to asynchronously communicate between threads.您应该使用互斥保护或 volatile 变量在线程之间进行异步通信。 Set that variable from one thread and check it in another.从一个线程设置该变量并在另一个线程中检查它。 Then reset its value and repeat.然后重置其值并重复。 A simple snippet:一个简单的片段:

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);
}

Using pthread_cancel() is an option, but I would not suggest doing it.使用pthread_cancel()是一种选择,但我不建议这样做。 You will have to check the threads state after this call returns, since pthread_cancel() does not wait for the actual thread stop.您必须在此调用返回后检查线程状态,因为pthread_cancel()不会等待实际线程停止。 And, which to me is even more important, I consider using it ugly.而且,对我来说更重要的是,我认为使用它很难看。

Using methods to stop a thread is a brute way.使用方法来停止线程是一种粗暴的方式。 You should rather politely ask the thread to stop by signalling.您应该礼貌地要求线程通过发出信号来停止。 Thereby the thread will have an option to tidy after itself eg if it has allocated memory, which it will not have any opportunity to do if the thread is cancelled.因此,线程将有一个选项来整理自己,例如,如果它已经分配了内存,如果线程被取消,它将没有任何机会这样做。

The method is relatively simple and comprises no OS signalling:该方法相对简单,不包括操作系统信令:

define a thread state variable or structure outside the thread.在线程外部定义线程状态变量或结构。 Point to it at the pthread_create and dereference the state variable in the thread.在 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.

It is even possible to communicate with the thread using a structure provided that it is simple 'atomic' variables or a simple handshake mechanism is established.甚至可以使用结构与线程进行通信,前提是它是简单的“原子”变量或建立了简单的握手机制。 Otherwise it may be necessary to use mutex.否则可能需要使用互斥锁。 Use pthread_join to wait for threads to terminate.使用 pthread_join 等待线程终止。

@Naruil's suggestion to call pthread_cancel() is pretty much the best solution i found, but it won't work if you didn't do the following things. @Naruil 建议调用pthread_cancel()几乎是我找到的最佳解决方案,但如果您不执行以下操作,它将无法工作。

According to the man-page of pthread_cancel the pthread_cancelibility depend on two thing根据pthread_cancel手册页, pthread_cancelibility 取决于两件事

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

thread_cancel_state is PTHREAD_CANCEL_ENABLE by default, so our main concern is about the thread_cancel_type , it's default value is type PTHREAD_CANCEL_DEFFERED but we need PTHREAD_CANCEL_ASYNCHRONOUS to set on that thread, which we wan't to cancel. thread_cancel_state默认是PTHREAD_CANCEL_ENABLE ,所以我们主要关心的是thread_cancel_type ,它的默认值是类型PTHREAD_CANCEL_DEFFERED但我们需要在该线程上设置PTHREAD_CANCEL_ASYNCHRONOUS ,我们不想取消。

Following an example given::下面给出一个例子:

#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;
}

run it using gcc filename.c -lpthread and output the following:: count -- 0 count -- 1 count -- 2 count -- 3 count -- 4使用gcc filename.c -lpthread运行它并输出以下内容: count -- 0 count -- 1 count -- 2 count -- 3 count -- 4

note that the done is never printed because the thread was canceled when the i became 5 & the running thread was canceled.请注意, done永远不会打印,因为当 i 变为 5 并且正在运行的线程被取消时线程被取消。 Special thanks @Naruil for the "pthread_cancel" suggestion.特别感谢@Naruil 的“pthread_cancel”建议。

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

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