How to stop a running pthread thread?

How can I immediately exit or stop the flow?

How can I make it stop immediately when the user enters a response? I want it to reset for each question.

Here is my code involving threading

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(); } } } } 
+4
source share
4 answers

Based on your code, I can give a simple answer:

In this case, do not use streams at all.

You do not need them. Save the start time, give a response to the user, check the time again after the user response.

 { 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 must use a variable protected by mutex or volatile for asynchronous communication between threads. Set this 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 this. You will need to check the status of the threads after this call returns, since pthread_cancel() does not wait for the thread to stop. And, more important to me, I find it ugly.

+9
source

You can simply call pthread_cancel in this thread to exit it. And you can send a SIGSTOP / SIGCONT signal through pthread_kill to stop / restart it.


But if all you need is a timer, why are you imposing it?

+8
source

Using methods to stop the flow is a crude way. You should politely ask the flow to stop by signaling. Thus, the stream will be able to arrange on its own, for example. if he allocated memory, which will not be able to do if the thread is canceled.

The method is relatively simple and does not contain OS signaling:

Define a stream state variable or off-stream structure. Point it to pthread_create and look for the state variable in the thread.

 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 stream using the structure, provided that these are simple “atomic” variables or a simple handshake mechanism. Otherwise, you may need to use a mutex. Use pthread_join to wait for threads to finish.

+3
source

@ Naruil's suggestion to call pthread_cancel () is the best solution I have found, but it will not work if you did not follow these steps.

According to the pthread_cancel man page, pthread_cancelibility depends on two things

  • thread_cancel_state.
  • thread_cancel_type.

thread_cancel_state by default is PTHREAD_CANCEL_ENABLE, so our main problem is thread_cancel_type , by default it is type PTHREAD_CANCEL_DEFFERED, but we need PTHREAD_CANCEL_ASYNCHRONOUS to set this thread, which we wan't to cancel.

Following an example:

 #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 with gcc filename.c -lpthread and print the following: count - 0 count - 1 count - 2 count - 3 count - 4

note that the done is never printed because the stream was canceled when I became 5 and the current stream was canceled. Special thanks to @Naruil for suggesting "pthread_cancel".

0
source

Source: https://habr.com/ru/post/1502396/


All Articles