Frage

Ich bin in ein paar Wochen zu einem Vorstellungsgespräch vorbereiten und ich thougth Ich würde Fäden in boost ein zu gehen, sowie tun die einfache Erzeuger / Verbraucher-Problem, das ich in der Schule gelernt haben.

Haben Sie es nicht schon geraume Zeit so war ich neugierig, was ihr davon halten? Was soll ich hinzufügen, es ist ein besseres Beispiel usw. Danke für das Feedback zu machen! :)

//////////////////////////////////////////////////////////////////////////
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;
}
War es hilfreich?

Lösung

Wenn Sie bereits Ihr Pufferobjekts in Anrufen wie addtobuffer und GetFromBuffer Einwickeln, würde es mehr Sinn macht für Sie die Verriegelung in Ihren Wrapper-Funktionen zu setzen. Darüber hinaus leisten Sie einen expliziten Aufruf entsperren, die vollständig den Zweck scoped_lock besiegt; scoped_lock Anwendungen Ressourcenerfassung ist Initialisierung (RAH) sowohl acquire und die Verriegelung lösen. Eine bessere Nutzung wäre den kritischen Abschnitt innerhalb eines Blockes zu platzieren, so dass der Mutex aufgrund der Sperre des Bereichs Ausgehen freigegeben wird und nicht aufgrund eines expliziten Aufruf der Unlock-Funktion, als Bereich weniger zerbrechlich ist. Zum Beispiel:

// 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top