多线程编程之pthread_cond_signal和pthread_cond_wait

在多线程编程中可能会碰到pthread_cond_signal和pthread_cond_wait使用不当而带来的诡异问题。今天说下我碰到的问题及解决思路,希望能对遇到类似问题的朋友有所帮助。

场景

场景示意图
场景如上图所示,场景说明如下:
首先启动ProcThread,启动后会创建对应的的ProcThreadQueue(先进先出)。并检测队列如果为空则执行pthread_cond_wait()等待被唤醒,消息出队,处理。伪代码如下:

void proc_thread(void)
{
	pthread_mutext_lock(&mutex);
	while(queue.empty())
	{
		pthread_cond_wait(&cond);
		pthread_mutext_lock(&mutex);
		queue.dequeue();
		....
		pthread_mutex_unlock(&mutex);
	}
}

然后启动Thread1,Thread2和Thread3,这3个线程都是从socket收消息,然后对ProcThreadQueue加锁,入队,解锁,然后唤醒ProcThread。伪代码如下:

void recv_thead()
{
	while(1)
	{
		....
		pthead_mutex_lock(&mutex);
		queue.enque();
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&cond);
	}
}

问题

在程序运行过程中出现发送消息方,收到相应消息比较慢导致出现超时错误。
抓包分析发现接收线程入队的消息,有时会需要大概25-30s左右才能被ProcThread接受处理,从而导致出现超时错误。
思路1:ProcThread没有被及时唤醒,导致消息处理慢,
验证1:将pthead_cond_signal换成pthread_cond_broadcast,问题依然没解决。

思路2:ProcThread被唤醒,线程锁阻塞,导致处理消息时间变长。
验证2:将pthread_cond_signal(&cond)放在解锁之前,先通知ProcThread,然后再释放线程锁,问题得到解决。
伪代码如下:

void recv_thead()
{
	while(1)
	{
		....
		pthead_mutex_lock(&mutex);
		queue.enque();
		pthread_cond_signal(&cond); //先通知线程等待
		pthread_mutex_unlock(&mutex);
	}
}

后续

  1. 网上有文章分析说先通知线程会有性能问题,这个没有验证。如果对消息处理时间没有要求的场景,可以考虑放在解锁之后。
  2. 线程锁阻塞导致处理消息等待25-30s,这个时间感觉时间比较长。后续有机会找方法会继续验证这个时间为什么会如此长。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值