C'è un problema con questo utilizzo del codice di condizione boost?
-
06-07-2019 - |
Domanda
Questo codice attenderà mai il mutex all'interno del void push (data)
del produttore?
Se sì, come posso aggirarlo?
boost::mutex access;
boost::condition cond;
// consumer
data read()
{
boost::mutex::scoped_lock lock(access);
// this blocks until the data is ready
cond.wait(lock);
// queue is ready
return data_from_queue();
}
// producer
void push(data)
{
//<--- will a block ever happen here?
boost::mutex::scoped_lock lock(access);
// add data to queue
cond.notify_one();
}
Diciamo che ho un pool di thread per il ciclo (;;) e che read () viene chiamato da un thread in questo pool. Quindi elaboro i dati su di esso. E chiamo push () con qualche thread esterno. La mia domanda è: quel thread esterno può mai bloccare la sua chiamata a push (dati)?
Soluzione
Quando viene chiamato .wait (), bloccherà il thread chiamante nel pool di thread e rilascerà il mutex. Restituirà quando qualcuno chiama notification_one () o notify_all (). Prima che il thread bloccato ritorni, acquisirà nuovamente il mutex e sbloccherà il thread nel pool di thread.
Quindi la chiamata a void push (data)
da parte del tuo thread esterno si bloccherà temporaneamente fino a quando non viene chiamato .wait ().
Consulta la la documentazione di boost sulla funzione di attesa della condizione .
Altri suggerimenti
wait
può tornare senza notifica
mai chiamato. Questo si chiama risveglio spurio . Per gestirlo, il codice che utilizza una condizione dovrebbe sempre avere un ciclo attorno al wait
che verifica che la condizione prevista sia realmente attiva. Ad esempio:
queue data_queue;
boost::mutex access;
boost::condition cond;
// consumer
data read()
{
boost::mutex::scoped_lock lock(access);
while (queue.is_empty()) {
// this blocks until the data is ready
cond.wait(lock);
}
// queue is ready
return data_from_queue();
}
// producer
void push(data)
{
boost::mutex::scoped_lock lock(access);
// add data to queue
queue.push_back(data);
cond.notify_one();
}
Concettualmente, "condizione" è un po 'fuorviante. Invece puoi pensarlo come un segnale. Stai segnalando un altro thread o thread per svegliarti, ma non stai promettendo nulla. Solo, " Ehi, forse ci sono alcuni dati pronti, perché non vai a controllare eh? & Quot;