desbloqueio espúria em fio de impulso
-
05-07-2019 - |
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?
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.