1 |
|
这是一个简单的消息队列,开启多个生产者多个消费者线程使用该消息队列,使用互斥锁和条件变量进行同步。以上是通过测试的最终版本,在实际写的过程中遇到了一些小问题。
1 | //takeMg |
以上是错误代码和最终代码的对比。可以看到,仅仅是修改了比较符,但影响很大。
在刚开始,写有问题的那段代码时,我是这样想的,需要把非空条件的集合唤醒,说明当前肯定是空变为非空了。比方说A、B都在等待非空条件,C投入一个资源,队列由空变为非空,唤醒A、B中的一个,比如说A。然后A拿走资源,队列再次变为空。C再投入一个资源,发现队列又由空变为非空,再次唤醒B。
似乎运行的很好。但是问题在于pthread_cond_signal的含义,由于我们是在锁内唤醒,即使唤醒也不能立刻拿到锁。所以pthread_cond_signal的含义是把线程从等待条件队列中移到等待互斥锁的队列里,并不是意味着唤醒就代表着它会是下一个拿到锁的线程,还是得经过在互斥锁队列里的竞争。
所以在刚才的步骤里就可能出现这种情况,C投入资源唤醒了A,A加入互斥锁队列,C再一次抢到了锁,这次因为资源数由1变为2,所以没有唤醒过程,如果C不再投入资源,那么B将永远醒不过来,一直在条件队列里。这也是我在实验的时候,程序一直停不下来。