Внедрение производителя / потребителя - Требуется обратная связь - PullRequest
1 голос
/ 25 мая 2010

Я готовлюсь к собеседованию через несколько недель, и, думаю, я бы дал темы для ускорения, а также выполнил бы простую задачу производителя / потребителя, которую я изучил в школе.

Не так давно, поэтому мне было интересно, что вы, ребята, думаете об этом? Что я должен добавить, чтобы сделать его лучшим примером и т. Д. Спасибо за отзыв! :)

//////////////////////////////////////////////////////////////////////////
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 Ответ

3 голосов
/ 25 мая 2010

Если вы уже оборачиваете свой буферный объект в вызовы, такие как AddToBuffer и GetFromBuffer, для вас будет более разумно поместить блокировку в функции-обертки. Кроме того, вы делаете явный вызов для разблокировки, что полностью противоречит цели scoped_lock; scoped_lock использует Resource Acquisition is Initialization (RAII) для получения и снятия блокировки. Лучше было бы поместить критическую секцию в блоке так, чтобы мьютекс освобождался из-за выхода блокировки из области видимости, а не из-за явного вызова функции разблокировки, поскольку области видимости менее хрупки. Например:

// 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...