为什么在信号处理程序中使用互斥锁会出现问题?
Why it is problematic to use mutex locks within signal handers?
下面是有问题的伪代码:
int c;
pthread_mutex_t mtx;
void inc(int count)
{
pthread_mutex_lock(&mtx);
c += count;
pthread_mutex_unlock(&mtx);
}
int main(void)
{
pthread_mutex_init(&mtx);
signal(SIGUSR1, inc);
signal(SIGUSR2, inc);
sleep(100000); // Sleep for long enough
return 0;
}
这段代码如何以及为什么会导致死锁?
为什么这与以下情况不同:
- Thread 1 acquires the mutex.
- Context switch is made and Thread 2 tries to get the lock and put on waiting list.
- Thread 1 finishes and releases the lock.
- Thread 2 wakes up and continues its execution.
- No deadlock.
您不能在信号处理程序中使用互斥锁,因为信号是异步的。你无法预测它们的发生。
如果在线程已经获取锁时发出信号,则会导致死锁。
信号处理程序在线程释放锁之前无法获取锁,但线程无法释放锁,因为在处理程序未完成之前无法恢复。
您的信号处理程序都将在同一个线程中 运行。如果第二个信号到达而第一个信号的处理程序已锁定互斥锁,则您的单独线程将再次尝试锁定互斥锁和死锁:
time thread 0
---- --------
0 main:...
1 main:sleep()
... ...
100 <<SIGUSR1>>
101 inc:pthread_mutex_lock()
102 inc:count += ...
103 <<SIGUSR2>>
104 inc:pthread_mutex_lock() // deadlock
下面是有问题的伪代码:
int c;
pthread_mutex_t mtx;
void inc(int count)
{
pthread_mutex_lock(&mtx);
c += count;
pthread_mutex_unlock(&mtx);
}
int main(void)
{
pthread_mutex_init(&mtx);
signal(SIGUSR1, inc);
signal(SIGUSR2, inc);
sleep(100000); // Sleep for long enough
return 0;
}
这段代码如何以及为什么会导致死锁?
为什么这与以下情况不同:
- Thread 1 acquires the mutex.
- Context switch is made and Thread 2 tries to get the lock and put on waiting list.
- Thread 1 finishes and releases the lock.
- Thread 2 wakes up and continues its execution.
- No deadlock.
您不能在信号处理程序中使用互斥锁,因为信号是异步的。你无法预测它们的发生。
如果在线程已经获取锁时发出信号,则会导致死锁。
信号处理程序在线程释放锁之前无法获取锁,但线程无法释放锁,因为在处理程序未完成之前无法恢复。
您的信号处理程序都将在同一个线程中 运行。如果第二个信号到达而第一个信号的处理程序已锁定互斥锁,则您的单独线程将再次尝试锁定互斥锁和死锁:
time thread 0
---- --------
0 main:...
1 main:sleep()
... ...
100 <<SIGUSR1>>
101 inc:pthread_mutex_lock()
102 inc:count += ...
103 <<SIGUSR2>>
104 inc:pthread_mutex_lock() // deadlock