在多线程程序中使用信号处理程序的时候,一定要注意,信号处理函数中一定不能使用锁,信号处理函数应该尽可能的简单,最好只是对于一些标志位的赋值,然后再其他线程中,对标志位进行轮询查看,在线程中处理更多的逻辑。先上程序
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#define THREAD_NUM 10
pthread_t tid[10];
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void sig_handler(int sig)
{
pthread_mutex_lock(&mutex);
printf("sig_handler\n");
pthread_mutex_unlock(&mutex);
}
void *thread_handler(void *arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("%ld thread_handler\n", pthread_self());
usleep(1000);
pthread_mutex_unlock(&mutex);
}
}
void *t_handler(void *arg)
{
while (1)
{
printf("%ld thread_handler\n", pthread_self());
usleep(1000);
}
}
int main()
{
signal(SIGINT, sig_handler);
int i;
for (i = 0; i < THREAD_NUM; i++)
{
pthread_create(&tid[i], NULL, thread_handler, NULL);
}
pthread_t t;
pthread_create(&t, NULL, t_handler, NULL);
for (i = 0; i < THREAD_NUM; i++)
{
pthread_join(tid[i], NULL);
}
return 0;
}
程序很简单,就是一个信号处理,还有十个线程,而且信号处理函数和这十个线程都使用同一个锁。在编译完运行后, 不断的使用CTRL+C,给程序发中断,最后程序运行会卡住,即使没有加锁的线程也会因为被信号中断,而信号中断函数被锁住而无法继续运行。下面为pstack看到的堆栈信息:
Thread 12 (Thread 0x7f7f47a6a700 (LWP 15083)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 11 (Thread 0x7f7f47069700 (LWP 15084)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 10 (Thread 0x7f7f46668700 (LWP 15085)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 9 (Thread 0x7f7f45c67700 (LWP 15086)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 8 (Thread 0x7f7f45265700 (LWP 15087)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 7 (Thread 0x7f7f44864700 (LWP 15088)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 6 (Thread 0x7f7f43e63700 (LWP 15089)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 5 (Thread 0x7f7f43462700 (LWP 15090)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 4 (Thread 0x7f7f42a61700 (LWP 15091)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a778acb8d in nanosleep () from /lib64/libc.so.6
#6 0x0000003a778e1d64 in usleep () from /lib64/libc.so.6
#7 0x0000000000400801 in thread_handler ()
#8 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#9 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 3 (Thread 0x7f7f42060700 (LWP 15092)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c0e052 in __lll_lock_wait () from /lib64/libpthread.so.0
#6 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#7 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#8 0x00000000004007d5 in thread_handler ()
#9 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7f7f4165f700 (LWP 15093)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a778acb8d in nanosleep () from /lib64/libc.so.6
#6 0x0000003a778e1d64 in usleep () from /lib64/libc.so.6
#7 0x0000000000400845 in t_handler ()
#8 0x0000003a77c07851 in start_thread () from /lib64/libpthread.so.0
#9 0x0000003a778e890d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f7f47a6c700 (LWP 15082)):
#0 0x0000003a77c0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003a77c09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003a77c09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00000000004007a9 in sig_handler ()
#4 <signal handler called>
#5 0x0000003a77c080ab in pthread_join () from /lib64/libpthread.so.0
#6 0x00000000004008d5 in main ()
可以看到,线程中会存在<signal handler called>,也就是说线程被信号中断了,而信号中断了的线程,可能正好获得了锁,正在运行printf或者usleep程序,还没释放锁,这时候信号来了,将该线程中断,去处理信号处理函数,信号处理函数sig_handler也需要获得该锁,结果就导致了信号处理函数获取不了锁,而被信号中断的线程也无法继续运行,程序就被卡死了。
先随便写写,后续可能再补充