为什么在信号处理程序中使用互斥锁是有问题的?

时间:2015-09-05 13:05:56

标签: c multithreading signals mutex 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;
}

此代码如何以及为何会导致死锁?

为什么这与以下情况不同:

  
      
  1. 线程1获取互斥锁。
  2.   
  3. 进行上下文切换,线程2尝试获取锁定并等待等待列表。
  4.   
  5. 线程1完成并释放锁。
  6.   
  7. 线程2醒来并继续执行。
  8.   
  9. 没有死锁。
  10.   

2 个答案:

答案 0 :(得分:3)

您的信号处理程序都将在同一个线程中运行。如果第一个信号到达而第一个信号的处理程序锁定了互斥锁,那么你的唯一线程将再次尝试锁定互斥锁和死锁:

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

答案 1 :(得分:1)

您不能在信号处理程序中使用互斥锁,因为信号是异步的。你无法预测它们的发生。

如果线程已经获得锁定时引发信号,则会导致死锁。

在线程释放锁之前,信号处理程序无法获取锁,但是线程无法释放锁,因为如果没有完成处理程序,它就无法恢复。