Uso de la variable de condición en una situación productor-consumidor


Estoy tratando de aprender sobre las variables de condición y cómo usarlo en una situación de productor-consumidor. Tengo una cola donde un hilo empuja números en la cola, mientras que otro hilo apareciendo los números de la cola. Quiero usar la variable de condición para señalar el subproceso consumidor cuando hay algunos datos colocados por el subproceso productor. El problema es que hay veces (o la mayoría de las veces) que solo empuja hasta dos elementos en la cola y luego se cuelga. He indicado en la función produce() donde se detiene cuando se ejecuta en modo de depuración. ¿Alguien puede ayudarme a señalar por qué está pasando esto?

Tengo las siguientes variables globales:


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

A continuación está mi hilo de consumo:


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();
        }
    }
}

A continuación está mi hilo productor:


void produce()
{
    int i = 0;

    while(( !bStop ) && ( i &lt MESSAGE ))    // MESSAGE currently set to 10
    {
        stringstream out;
        out &lt&lt 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();
    }
}
Author: jasonline, 2010-03-04

1 answers

Debe usar el mismo mutex para proteger la cola que usa en la variable condition.

Esto debería ser todo lo que necesitas:

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();
    }
}
 35
Author: nos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-04 14:17:51