代码之家  ›  专栏  ›  技术社区  ›  bobber205

生产者/消费者实施-需要反馈

  •  1
  • bobber205  · 技术社区  · 16 年前

    很久没做了所以我很好奇你们怎么看?我应该补充什么,使它成为一个更好的例子等。感谢您的反馈!:)

    //////////////////////////////////////////////////////////////////////////
    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;
    }
    
    1 回复  |  直到 16 年前
        1
  •  3
  •   Michael Aaron Safyan    16 年前

    如果您已经在AddToBuffer和GetFromBuffer之类的调用中包装了缓冲区对象,那么在包装器函数中设置锁会更有意义。此外,您正在显式调用unlock,这完全违背了作用域锁定的目的;作用域锁定使用资源获取is初始化(RAII)来获取和释放锁。更好的用法是将关键部分放在块中,这样由于锁超出作用域而释放互斥锁,而不是由于显式调用unlock函数,因为作用域不那么脆弱。例如:

    // 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