c++11 多线程生产者消费者模型

一段简单的示例代码

#include 
#include 
#include 
#include 
int i = 0;
std::mutex mtx;
std::condition_variable condition_in, condition_out;
void in(int id)
{
    while (true)
    {
        //(1)
        std::unique_lock in(mtx);
        condition_in.wait(in, [id](){
            std::cout << "condition_in.wait id:" << id << std::endl;
            return i < 5; 
        });
        std::cout << "thread id:"<"<<++i< in(mtx);
        condition_out.wait(in, [id](){
            std::cout << "condition_out.wait id: " << id < 1;
        });
        i -= 2;
        std::cout << "thread id:" << id<<"# "<<"===>" <

std::unique_lock

std::unique_lock 是一个使用RAII机制来管理 std::mutex 的一个类,相比于 std::lock_guard 有更灵活的方式,但会比 std::lock_guard 使用更多的空间。

Member functions

Locking/unlocking

lock
try_lock
try_lock_for
try_lock_until
unlock

Modifiers

operator= (Move-assign unique_lock)
swap
release

Observers

owns_lock
operator bool (Return whether it owns a lock)
mutex

运行结果

单消费者单生产者

condition_in.wait id:0
thread id:0# ===>1
condition_out.wait id: 1
condition_in.wait id:0
thread id:0# ===>2
condition_in.wait id:0
thread id:0# ===>3
condition_out.wait id: 1
thread id:1# ===>1
condition_in.wait id:0
thread id:0# ===>2
condition_out.wait id: 1
thread id:1# ===>0
condition_in.wait id:0
thread id:0# ===>1
condition_out.wait id: 1
condition_in.wait id:0
thread id:0# ===>2
condition_in.wait id:0
thread id:0# ===>3
condition_out.wait id: 1
thread id:1# ===>1
condition_in.wait id:0
thread id:0# ===>2
condition_out.wait id: 1
thread id:1# ===>0

结果大致如预期,但是通过观察发现产品的个数总是以0->1->2->3->1->2->0的规律变化,按理说每次产品增加到2之后唤醒消费者线程应该就会将2个产品取走了。通过分析输出日志,应该是因为被condition阻塞的线程从唤醒到重新上锁的时间要长于 std::unique_lock 锁争用时直接上锁的时间。另外,启动消费者和生产者线程的先后顺序也会影响刚开始的输出序列,但整体的变化规律不会变。在(1)处插入

if(i > 1)

然后先启动t2,再启动t1线程,仍然可以观察到相同序列,基本证明猜想正确。
多消费者多生产者的情况也完全符合预期。不过经过一番尝试,并没有模拟出虚假唤醒的情况,有待进一步考察。

你可能感兴趣的:(c++11 多线程生产者消费者模型)