0

I have this question:

  • How can I kill a thread (maybe with pthread_cancel()) from another thread?

Here is the sample code. I need that when I press 1, the other thread gets killed. (I must force the kill from one thread without putting a pthread_exit() in the other.)

pthread_t THR_INPUT, THR_QUEUE;

void *thr_in(void *null) {
    int opt;
    while(1){
        printf("1. Kill the other thread\n");
        scanf("%d", &opt);

        switch (opt)
        {
            case 1: 
                pthread_cancel(THR_QUEUE);
                pthread_exit(NULL);
            default:
                printf("ATTENZIONE: Scelta %i non corretta. Riprovare.\n",opt);

        }
    }
}

void *thr_qu(int reparto) {
    while(1){
    sleep(2);
    printf("I'm alive!");    
    }
}

int main(int argc, const char * argv[]){
    void *result;   

    printf("-------start-------\nMenu:\n");
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&THR_INPUT, NULL, thr_in, NULL);
    pthread_create(&THR_QUEUE, NULL, thr_qu(reparto), NULL);
    pthread_join(THR_INPUT, &result);
    pthread_join(THR_QUEUE, &result);
    printf("---end---\n");
    exit(EXIT_SUCCESS);
}

I think about a solution but I don't know how clean it is; just do this:

int main(int argc, const char * argv[]){
    void *result;
    sem = semget(SEM_KEY, 0, 0); 
    pthread_mutex_init(&mutex, NULL);
    int pid=getpid();
    pid=fork();
    if(!pid){
    printf("-------START-------\nMenu:\n");
    pthread_create(&THR_INPUT, NULL, thr_in, NULL);
    pthread_create(&THR_QUEUE, NULL, thr_qu(reparto), NULL);
    pthread_join(THR_INPUT, &result);
    pthread_join(THR_QUEUE, &result);
    }
    else{
        wait(sem,0);
        pthread_cancel(THR_QUEUE);
        printf("---END---\n");
    }
    exit(EXIT_SUCCESS);
}

and putting a signal in the first thread that, when it is asked to exit, signal to the semaphore in main thread to do the pthread_cancel(). But it still not working, and i dont know why

MarkWarriors
  • 544
  • 2
  • 9
  • 17
  • 1
    This is worng: `pthread_create(&THR_QUEUE, NULL, thr_qu(reparto), NULL);`, should be `pthread_create(&THR_QUEUE, NULL, thr_qu, reparto)` What – Jonatan Goebel Apr 24 '13 at 19:37
  • Uhm, in your way I can't compile.. I think that I make a mistake setting void *thr_qu(int reparto), so i rewrite void *thr_qu(void *null), and called the pthread_create(&THR_QUEUE, NULL, thr_qu, NULL). Anyway I am really new in the thread argument, so i must learn much thing, like how can pass some value to the thread from the main. – MarkWarriors Apr 24 '13 at 23:50
  • Declare your thread function like this: 'void *thr_qu(void *arg)'. Create them like this: 'pthread_create(&THR_QUEUE, NULL, thr_qu, &reparto)'. And inside the thr_qu function do this 'int reparto = *arg;' But you must pay attention doing this, because "&reparto" cannot point to a local variable, unless it is static. – Jonatan Goebel Apr 25 '13 at 12:41
  • The short answer to this kind of question is this: Without the thread's cooperation, you cannot cancel or kill it sanely. With the thread's cooperation, you can do it however you like. – David Schwartz Jan 07 '14 at 21:04

1 Answers1

3

You can use pthread_cancel, but it's only a request to the target thread, not a forcible kill. What distinguishes cancellation from other forms of requests, such as a flag communicated via a condition variable, is that:

  1. Cancellation is automatically acted upon at certain standard library calls, called cancellation points, unless the target thread has specifically suspended cancellation.

  2. Cancellation can work even when the target thread is blocked waiting for IO or certain other events that might never complete (in which case, it's the only way to stop them).

To use cancellation correctly, you must either make heavy use of pthread_cleanup_push at each level of resource allocation or major state change to ensure that all partial changes are backed out when a thread is cancelled, or you must block cancellation with pthread_setcancelstate except at certain points where it would be safe to act on cancellation with little or no cleanup effort.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    You can use pthread_cancel to force a cancellation, just need to set the `canceltype` of the thread first. http://linux.die.net/man/3/pthread_setcanceltype . And sleep is a cancellation point, so his code should work after fix the pthread_create call. Anyway +1 for the good explanation. – Jonatan Goebel Apr 24 '13 at 19:56
  • @JonatanGoebel: Only the target thread can set the cancellation type or state, so a different thread has no way to forcibly cancel it. Moreover, asynchronous cancellation (which you seem to be suggesting) is not safe except on purely computational code. (Only three functions in the whole standard library are async-cancel-safe.) – R.. GitHub STOP HELPING ICE Apr 24 '13 at 22:02
  • Well, is just for try, I have set the cancelstate, and then the program work. I know that isn't a clean way, but I am also a little bit angry cause is an exercise that my professor gave to me without explain anything except how create thread and how wait for them in the main -_-' Anyway nice explanation, thank you! – MarkWarriors Apr 24 '13 at 23:55