条件变量与互斥锁

一般的用法:

线程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会超时的锁

你可能感兴趣的:(c++,开发语言)