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)?

È stato utile?

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;

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top