Domanda

sto cercando di conoscere le variabili di condizione e come usarlo in una situazione di produttore-consumatore. Ho una coda in cui un filo spinge i numeri nella coda mentre un altro thread popping numeri dalla coda. Voglio usare la variabile di condizione per segnalare il filo consumare quando ci sono alcuni dati inseriti dal filo producendo. Il problema è che ci sono volte (o la maggior parte delle volte) che spinge solo fino a due voci nella coda poi si blocca. Ho indicato nella funzione dei prodotti () dove si ferma durante l'esecuzione in modalità di debug. Chiunque può aiutare me sottolineare perché questo sta accadendo?

Ho le seguenti variabili globali:


boost::mutex mutexQ;               // mutex protecting the queue
boost::mutex mutexCond;            // mutex for the condition variable
boost::condition_variable condQ;

Di seguito è riportato il mio thread consumatore:


void consume()
{
    while( !bStop )   // globally declared, stops when ESC key is pressed
    {
        boost::unique_lock lock( mutexCond );
        while( !bDataReady )
        {
            condQ.wait( lock );
        }

        // Process data
        if( !messageQ.empty() )
        {
            boost::mutex::scoped_lock lock( mutexQ );

            string s = messageQ.front();   
            messageQ.pop();
        }
    }
}

Di seguito è riportato il mio thread produttore:


void produce()
{
    int i = 0;

    while(( !bStop ) && ( i < MESSAGE ))    // MESSAGE currently set to 10
    {
        stringstream out;
        out << i;
        string s = out.str();

        boost::mutex::scoped_lock lock( mutexQ );
        messageQ.push( s );

        i++;
        {
            boost::lock_guard lock( mutexCond );  // HANGS here
            bDataReady = true;
        }
        condQ.notify_one();
    }
}
È stato utile?

Soluzione

Si deve utilizzare lo stesso mutex a guardia della coda come si usa nella variabile condizioni.

Questo dovrebbe essere tutto ciò che serve:

void consume()
{
    while( !bStop )
    {
        boost::scoped_lock lock( mutexQ);
        // Process data
        while( messageQ.empty() ) // while - to guard agains spurious wakeups
        {
            condQ.wait( lock );

        }
        string s = messageQ.front();            
        messageQ.pop();
    }
}

void produce()
{
    int i = 0;

    while(( !bStop ) && ( i < MESSAGE ))
    {
        stringstream out;
        out << i;
        string s = out.str();

        boost::mutex::scoped_lock lock( mutexQ );
        messageQ.push( s );
        i++;
        condQ.notify_one();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top