美文网首页
c++11 多线程生产者消费者模型

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

作者: 红茶ovo | 来源:发表于2017-05-16 20:15 被阅读0次

一段简单的示例代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
int i = 0;
std::mutex mtx;
std::condition_variable condition_in, condition_out;
void in(int id)
{
    while (true)
    {
        //(1)
        std::unique_lock<std::mutex> in(mtx);
        condition_in.wait(in, [id](){
            std::cout << "condition_in.wait id:" << id << std::endl;
            return i < 5; 
        });
        std::cout << "thread id:"<<id<<"# "<<"===>"<<++i<<std::endl;
        //(2)
        condition_out.notify_one();
        //(3)
    }
}
void out(int id)
{
    while (true)
    {
        std::unique_lock<std::mutex> in(mtx);
        condition_out.wait(in, [id](){
            std::cout << "condition_out.wait id: " << id <<std::endl;
            return i > 1;
        });
        i -= 2;
        std::cout << "thread id:" << id<<"# "<<"===>" <<i << std::endl;
        condition_in.notify_one();
    }
}
void main()
{
    std::thread t1(in,0);
    std::thread t2(out,1);
    //std::thread t3(out,2);
    //std::thread t4(out,3);
    //std::thread t5(out,4);

    t1.join();
}

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<std::mutex> 锁争用时直接上锁的时间。另外,启动消费者和生产者线程的先后顺序也会影响刚开始的输出序列,但整体的变化规律不会变。在(1)处插入

if(i > 1)

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

相关文章

网友评论

      本文标题:c++11 多线程生产者消费者模型

      本文链接:https://www.haomeiwen.com/subject/cjfrxxtx.html