c++ - 生产者/消费者实现——需要反馈

标签 c++ boost multithreading producer-consumer

我正在准备几周后的面试,我想我会试一试 boost 中的线程,以及我在学校学到的简单的生产者/消费者问题。

好久没做了,所以我很好奇你们对此有何看法?我应该添加什么以使其成为更好的示例等。感谢您的反馈! :)

//////////////////////////////////////////////////////////////////////////
boost::mutex bufferMutex;
deque<int> buffer;
const int maxBufferSize = 5;
//////////////////////////////////////////////////////////////////////////

bool AddToBuffer(int i)
{
    if (buffer.size() < maxBufferSize)
    {
        buffer.push_back(i);
        return true;
    }
    else
    {       
        return false;
    }
}

bool GetFromBuffer(int& toReturn)
{
    if (buffer.size() == 0)
    {
        return false;
    }
    else
    {
        toReturn = buffer[buffer.size()-1];
        buffer.pop_back();
        return true;
    }
}

struct Producer 
{
    int ID;
    void operator()()
    {
        while (true)
        {
            boost::mutex::scoped_lock lock(bufferMutex);
            int num = dice();
            bool result = AddToBuffer(num);
            lock.unlock();
            //safe area done
            if (result)
            {
                cout << "Producer " << this->ID << " Added " << num << endl;
            }
            else
            {
                cout << "!!Buffer was Full!!" << endl;
            }
            //Added
            //Now wait
            boost::xtime xt;
            xtime_get( &xt, boost::TIME_UTC);
            xt.nsec += 1000000 + 100000 * (rand() % 1000);
            boost::thread::sleep(xt);
        }
    }
};

struct Consumer 
{
    int ID;
    void operator()()
    {
        while (true)
        {
            int returnedInt = 0;
            boost::mutex::scoped_lock lock(bufferMutex);
            bool result = GetFromBuffer(returnedInt);
            lock.unlock();
            //safe area done
            if (result)
            {
                cout << "\tConsumer " << this->ID << " Took Out " << returnedInt << endl;
            }
            else
            {
                cout << "!!Buffer was Empty!!" << endl;
            }
            //Added
            //Now wait
            boost::xtime xt;
            xtime_get( &xt, boost::TIME_UTC);
            xt.nsec += 1000000 + 100000 * (rand() % 1000);
            boost::thread::sleep(xt);
        }
    }
};



void main()
{
    Producer p, p2;
    Consumer c, c2;

    p.ID = 1;
    p2.ID = 2;

    c.ID = 1;
    c2.ID = 2;

    boost::thread thread1(boost::ref(p));
    boost::thread thread2(boost::ref(c));
    boost::thread thread3(boost::ref(p2));
    boost::thread thread4(boost::ref(c2));

    int x;
    cin >> x;
}

最佳答案

如果您已经在 AddToBuffer 和 GetFromBuffer 等调用中包装了缓冲区对象,那么将锁定放在包装函数中会更有意义。此外,您正在显式调用 unlock,这完全违背了 scoped_lock 的目的; scoped_lock 使用 Resource Acquisition is Initialization (RAII) 来获取和释放锁。更好的用法是将关键部分放在一个 block 中,以便由于锁超出范围而不是由于显式调用解锁函数而释放互斥锁,因为范围不那么脆弱。例如:

// Code that doesn't need locking
{
    boost::mutex::scoped_lock lck(bufferMutex); // Lock is acquired here
    // Code that needs to be synchronized
} // Lock is automatically released here without explicit call to unlock()
// More code that doesn't need locking

关于c++ - 生产者/消费者实现——需要反馈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2900357/

相关文章:

c++ - 无法对包含字符串 C++ 的结构数组进行操作

c++ - Boost:boost::slot<>::~slot 崩溃的原因可能是什么?

java - 如果两个线程使用不同的监视器,它们是否可以在同一个对象上执行相同的同步代码块?

c++ - 串行端口线程的 CPU 消耗

c++ - 我应该使用 operator+= 而不是 operator+ 来连接 std::string 吗?

c# - 帮助我将以下 VB/C++ 代码转换为 C#

java - 读取 netflow/rflow (dd-wrt) 数据包内容

c++ - 使用 boost::assign::list_of 和 boost::variant

c++ - 返回 boost::smatch 并获取子串 "\000"

java - CountDownLatch 在 Java 中如何工作?