2013-04-24 197 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