我已经在线程池中处理问题了好几天了。我尝试了所有类型的不同的东西,但我似乎无法解决这个问题。我做了一个简单的版本来重现这个问题。
代码:
#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;
}
答案 0 :(得分:2)
pthread_exit()未列在signal(7)手册页的“信号安全功能”中。 重写你的代码,让pthread_exit调用在信号处理程序之外。