2013-04-24 169 views
0

線程我有這樣的疑問:殺從另一個線程

  • 我怎麼能殺死一個線程(可能與pthread_cancel())從另一個線程?

以下是示例代碼。 我需要,當我按1,其他線程被殺害。 (我必須強制殺死一個線程,而又不會讓pthread_exit()的除外)。

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

我想到一個解決方案,但我不知道它是多麼乾淨;只是這樣做:

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

,並把信號在第一線,當它被要求退出,信號在主線程的信號做pthread_cancel()。但它仍然不工作,我不知道爲什麼

+1

這是撥錯:'在pthread_create(THR_QUEUE,NULL,thr_qu(reparto),NULL);',應該是'在pthread_create(THR_QUEUE,NULL,thr_qu,reparto)' 什麼 – 2013-04-24 19:37:57

+0

嗯,在你的方式,我不能編譯..我認爲我犯了一個錯誤設置void * thr_qu(int reparto),所以我重寫void * thr_qu(void * null),並調用pthread_create(&THR_QUEUE,NULL,thr_qu,NULL)。無論如何,我在線程參數中真的很新,所以我必須學習很多東西,比如如何將一些值傳遞給主線程中的線程。 – ReTanica 2013-04-24 23:50:07

+0

聲明你的線程函數是這樣的:'void * thr_qu(void * arg)'。像這樣創建它們:'pthread_create(&THR_QUEUE,NULL,thr_qu,&reparto)'。並且在thr_qu函數裏面做這個'int reparto = * arg;'但是你必須注意這樣做,因爲「&reparto」不能指向局部變量,除非它是靜態的。 – 2013-04-25 12:41:18

回答

3

您可以使用pthread_cancel,但它只是一個請求目標線程,而不是強行殺死。什麼其他形式的請求,比如通過一個條件變量通信的標誌,區分消除是:

  1. 取消是基於在一定的標準庫調用自動採取行動,稱爲取消點,除非目標線程已明確暫停取消。

  2. 取消可以工作,即使目標線程是阻塞等待IO或可能永遠不會完成(在這種情況下,這是阻止他們的唯一方法)的某些其他事件。

要正確使用取消,則必須使在資源分配或重大狀態改變的每個級別使用pthread_cleanup_push,以確保所有的局部變化支持了當一個線程被取消,或者您必須通過pthread_setcancelstate阻止取消,除非在某些情況下,在很少或根本沒有清理工作的情況下采取行動取消是安全的。

+1

你可以使用pthread_cancel強制取消,只需要先設置線程的'canceltype'。 http://linux.die.net/man/3/pthread_setcanceltype。 睡眠是一個取消點,所以他的代碼應該在修復pthread_create調用後工作。無論如何+1是很好的解釋。 – 2013-04-24 19:56:52

+0

@JonatanGoebel:只有目標線程可以設置取消類型或狀態,所以不同的線程無法強制取消它。此外,異步取消(您似乎暗示)除了純粹的計算代碼外並不安全。 (整個標準庫中只有三個函數是異步取消安全的。) – 2013-04-24 22:02:45

+0

嗯,只是爲了嘗試,我已經設置了cancelstate,然後程序工作。我知道這不是一種乾淨的方式,但我也有點生氣,因爲我的教授給我的練習沒有解釋任何東西,除了如何創建線程以及如何在主體中等待它們之外 - 「無論如何,好的解釋, 謝謝! – ReTanica 2013-04-24 23:55:45