条件变量与互斥锁

文章讨论了在Linux环境中,线程通过pthreadmutex和conditionvariable进行同步的情况,以及线程信号处理可能导致的数据竞争和死锁问题。线程A在等待条件满足时可能被信号中断,而信号处理函数在同一资源上操作时可能导致死锁。为解决这类问题,提出了使用多日志接口或带超时的锁(pthread_mutex_timedlock)作为潜在解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般的用法:

线程A

pthread_mutex_lock(&mutex);
while (false == ready)
{
     pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);

线程B

pthread_mutex_lock(&mutex);
ready = true;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);

pthread_cond_wait的内部流程是:调用的时候解锁mutex,信号触发后pthread_cond_wait返回,返回之前加锁mutex。

如果线程A先获取到 mutex,当时 ready 为 false,线程A 调用 pthread_cond_wait 进入等待状态,进入该函数的时候就会解锁 mutex,pthread_cond_wait 阻塞住了。解锁mutex线程B获取到mutex,修改 ready,调用pthread_cond_signal发送信号,此时pthread_cond_wait返回,返回之前会加锁mutex,跳出while循环,然后解锁mutex

如果 线程B先获取到mutex,然后修改 ready 为 true,然后解锁锁mutex,接下来线程A 获取到mutex,read是true,不会进入到while里面的逻辑,直接解锁mutex。

这里使用while,因为一般这种情况下线程A实例会被多次调用,生成多个线程,使用相同的逻辑。

linux有一个api叫做signal,就是处理某些信号的时候的回调,

在Linux中,当进程接收到信号时,内核会选择一个线程来处理该信号。这个线程通常是当前正在运行的线程或者是最后一个执行的线程,但是并不是绝对的,因为内核对于信号处理的选择是有一定的策略的。

具体来说,当进程接收到信号时,内核会将信号发送给进程中的某个线程,并让该线程来处理信号。如果当前没有正在运行的线程,则内核会选择最后一个执行的线程来处理信号。处理信号的线程会暂停当前的工作,转而执行信号处理函数,执行完信号处理函数之后再回到原来的工作。

需要注意的是,如果信号处理函数修改了全局变量或共享资源等,可能会导致多线程数据竞争的问题。因此,在多线程程序中,需要谨慎处理信号,避免出现竞争问题。

所以如果日志里面加锁了,signal的回调里面有写日志,可能会有问题:线程A正在写日志,申请了锁还没释放,进程收到signal回调,挂起了线程A,使用线程A处理回调,signal的回调里面准备写日志,结果申请锁的时候卡住了,因为锁已经被挂起的线程A占用了。导致signal的回调处理不了。线程A因为挂起了也释放不了锁,导致死锁。

这种情况下可以使用多日志接口,即不同的环境下使用不同的日志文件,或者使用pthread_mutex_timedlock会超时的锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值