C语言 如何停止正在运行的 pthread 线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18826853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop a running pthread thread?
提问by xDianneCodex
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();
}
}
}
}
回答by Naruil
You can simply call pthread_cancelon that thread to exit it. And you can send SIGSTOP/SIGCONT signal via pthread_killto stop/restart it.
您可以简单地调用pthread_cancel该线程以退出它。您可以通过发送 SIGSTOP/SIGCONT 信号pthread_kill来停止/重新启动它。
But if all you want is a timer, why must you thread?
但是,如果您只想要一个计时器,为什么必须线程?
回答by Dariusz
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. Set that variable from one thread and check it in another. Then reset its value and repeat. A simple snippet:
您应该使用互斥锁保护或 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);
}
Using pthread_cancel()is an option, but I would not suggest doing it. You will have to check the threads state after this call returns, since pthread_cancel()does not wait for the actual thread stop. And, which to me is even more important, I consider using it ugly.
使用pthread_cancel()是一种选择,但我不建议这样做。您必须在此调用返回后检查线程状态,因为pthread_cancel()不会等待实际线程停止。而且,对我来说更重要的是,我认为使用它很难看。
回答by 172Pilot
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 e.g. 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 等待线程终止。
回答by Ratul Sharker
@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_cancelthe pthread_cancelibility depend on two thing
根据pthread_cancel的 手册页,pthread_cancelibility 取决于两件事
- thread_cancel_state.
- thread_cancel_type.
- 线程取消状态。
- 线程取消类型。
thread_cancel_stateis PTHREAD_CANCEL_ENABLEby default, so our main concern is about the thread_cancel_type, it's default value is type PTHREAD_CANCEL_DEFFEREDbut we need PTHREAD_CANCEL_ASYNCHRONOUSto 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 -lpthreadand 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 doneis never printed because the thread was canceled when the i became 5 & the running thread was canceled. Special thanks @Naruil for the "pthread_cancel" suggestion.
请注意,done永远不会打印,因为当 i 变为 5 并且正在运行的线程被取消时线程被取消。特别感谢@Naruil 的“pthread_cancel”建议。

