分离的线程虽然运行pthread_exit但不会退出?

时间:2015-01-01 17:42:32

标签: c multithreading pthreads semaphore pthread-exit

我已经在线程池中处理问题了好几天了。我尝试了所有类型的不同的东西,但我似乎无法解决这个问题。我做了一个简单的版本来重现这个问题。

代码:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h> 


struct bsem_t bsem;
pthread_t threads[2];


/* Binary semaphore */
typedef struct bsem_t {
    pthread_mutex_t mutex;
    pthread_cond_t   cond;
    int v;
} bsem_t;

void bsem_post(bsem_t *bsem) {
    pthread_mutex_lock(&bsem->mutex);
    bsem->v = 1;
    pthread_cond_broadcast(&bsem->cond);
    pthread_mutex_unlock(&bsem->mutex);
}

void bsem_wait(bsem_t *bsem) {
    pthread_mutex_lock(&bsem->mutex);
    while (bsem->v != 1) {
        pthread_cond_wait(&bsem->cond, &bsem->mutex);
    }
    bsem->v = 0;
    pthread_mutex_unlock(&bsem->mutex);
}


/* Being called by each thread on SIGUSR1 */
void thread_exit(){
    printf("%u: pthread_exit()\n", (int)pthread_self());
    pthread_exit(NULL);
}


/* Startpoint for each thread */
void thread_do(){

    struct sigaction act;
    act.sa_handler = thread_exit;
    sigaction(SIGUSR1, &act, NULL);

    while(1){
        bsem_wait(&bsem); // Each thread is blocked here
        puts("Passed semaphore");
    }

}


/* Main */
int main(){

    bsem.v = 0;

    pthread_create(&threads[0], NULL, (void *)thread_do, NULL);
    pthread_create(&threads[1], NULL, (void *)thread_do, NULL);
    pthread_detach(threads[0]);
    pthread_detach(threads[1]);
    puts("Created threads");

    sleep(2);

    pthread_kill(threads[0], SIGUSR1);
    pthread_kill(threads[1], SIGUSR1);

    puts("Killed threads");

    sleep(10);

    return 0;
}

代码的作用是创建两个线程。两个线程都在等待二进制信号量( bsem_wait )。然后,当他们等待时,我发送一个SIGUSR1信号,导致pthread_exit()在每个线程上执行。在我的终端上,它显示一切都按计划进行..

输出:

Created threads
Killed threads
2695145216: pthread_exit()
2686752512: pthread_exit()

问题

虽然输出似乎正确,但使用pstree表示只有两个线程中的一个死亡。另一个线程保持活动状态,直到整个程序退出。这是为什么?


更新

用普通的信号量替换我的自定义二进制信号量似乎没有明显的原因解决这个问题。

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h> 
#include <semaphore.h> 

sem_t sem;
pthread_t threads[2];


/* Caller thread will exit */
void thread_exit(){
    printf("%u: pthread_exit()\n", (int)pthread_self());
    pthread_exit(NULL);
}


/* Startpoint for each thread */
void* thread_do(){

    struct sigaction act;
    act.sa_handler = thread_exit;
    sigaction(SIGUSR1, &act, NULL);

    while(1){
        sem_wait(&sem); // Each thread is blocked here
        puts("Passed semaphore");
    }

}


/* Main */
int main(){

    sem_init(&sem, 0, 0); // Normal semaphore

    pthread_create(&threads[0], NULL, thread_do, NULL);
    pthread_create(&threads[1], NULL, thread_do, NULL);
    pthread_detach(threads[0]);
    pthread_detach(threads[1]);
    puts("Created threads in pool");

    sleep(2);

    //PROBLEM
    pthread_kill(threads[0], SIGUSR1);
    pthread_kill(threads[1], SIGUSR1);

    puts("Destroyed pool");

    sleep(10);

    return 0;
}

1 个答案:

答案 0 :(得分:2)

你无法从这里到达那里

pthread_exit()未列在signal(7)手册页的“信号安全功能”中。 重写你的代码,让pthread_exit调用在信号处理程序之外。