Pergunta

Me deparei com este parágrafo interessante no documentação fio impulso hoje:

void wait(boost::unique_lock<boost::mutex>& lock)

...

Efeitos: atomicamente chamada lock.unlock () e bloqueia o segmento atual. o thread irá desbloquear quando notificado por um chamar a this-> notify_one () ou this-> notify_all () ou spuriously . Quando o segmento está desbloqueado (para qualquer motivo), o bloqueio é readquirido por lock.lock invocação () antes da chamada para esperar retornos. o de bloqueio também é readquirida invocando lock.lock () se as saídas de função com uma exceção.

Então, o que me interessa é o significado da palavra "falsamente". Por que o fio ser desbloqueado por razões espúrias? O que pode ser feito para resolver isso?

Foi útil?

Solução

Este artigo por Anthony Williams é particularmente detalhado .

velórios espúrias não podem ser previstas: eles são essencialmente aleatória da ponto de vista do usuário. No entanto, eles geralmente ocorrem quando a biblioteca de threads não pode garantir com segurança que uma espera thread não vai perder uma notificação. Desde uma notificação perdeu faria tornar a variável condição inútil, a biblioteca thread acorda o fio desde a sua espera, em vez de tomar o risco.

Ele também aponta que você não deve usar as sobrecargas timed_wait que levam uma duração, e você geralmente deve usar as versões que levam um predicado

Isso é erro de principiante, e um que é facilmente superada com um simples governar: verifique sempre o seu predicado em uma ciclo quando espera com uma condição variável. O bug mais insidioso vem de TIMED_WAIT ().

Este artigo de Vladimir Prus também é interessante.

Mas por que precisamos do loop while, Não podemos escrever:

if (!something_happened)
  c.wait(m);

Nós não podemos. E a razão assassino é que can 'espera' retornar sem qualquer chamada 'avisar'. Isso é chamado de despertar espúria e é explicitamente permitido pela POSIX. Essencialmente, o retorno de 'espera' única indica que o poder de dados compartilhados mudaram, de modo que os dados devem ser avaliada novamente.

Ok, então por que isso não é fixo ainda? A primeira razão é que ninguém quer para fixar isso. chamada embrulho para 'espera' em um circuito é muito desejada para várias outras razões. Mas essas razões necessitam de explicação, enquanto espúria despertar é um martelo que pode ser aplicado a qualquer estudante do primeiro ano sem Fail.

Outras dicas

Este post dá uma razão para Linux, em termos do sistema futex chamar retornar quando um sinal é entregue a um processo. Infelizmente não explica nada mais (e de fato está pedindo mais informações).

A entrada Wikipedia em wakeups espúrias (que parecem ser um conceito de grande POSIX, btw, não se limitando a boost) você pode interessar também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top