/ / Multithreading e seções críticas Use - C ++ - c ++, multithreading, visual-studio-2008, winapi, seção crítica

Seções críticas e multithread Use - C ++ - c ++, multithreading, visual-studio-2008, winapi, seção crítica

Estou um pouco confuso quanto ao uso adequado deseções críticas em aplicativos multithread. Na minha aplicação, existem vários objetos (alguns buffers circulares e um objeto de porta serial) que são compartilhados entre os threads. O acesso desses objetos deve sempre ser colocado dentro de seções críticas, ou apenas em determinados momentos? Eu suspeito apenas em certos momentos, porque quando eu tentei envolver cada uso com um EnterCriticalSection / LeaveCriticalSection Eu corri para o que parecia ser uma condição de impasse. Qualquer visão que você possa ter seria apreciada. Obrigado.

Respostas:

6 para resposta № 1

Se você compartilhar um recurso através de threads, e alguns desses threads lerem enquanto outros escrevem, então ele deve ser protegido sempre.

É difícil dar mais conselhos sem saber mais sobre o seu código, mas aqui estão alguns pontos gerais a serem lembrados.

1) seções críticas proteger Recursos, não processos.

2) Digite / deixe seções críticas no mesmoordem em todos os segmentos. Se a linha A entrar em Foo, entrar na barra, a linha B deverá inserir Foo e Bar na mesma ordem. Se você não, você poderia criar uma corrida.

3) Entrar e sair deve ser feito em ordem oposta. Exemplo, desde que você entrou Foo, em seguida, entrou Bar, você deve deixar Bar antes de sair Foo. Se você não fizer isso, você pode criar um impasse.

4) Mantenha as fechaduras pelo menor período de temporazoavelmente possível. Se você terminou com o Foo antes de começar a usar o Bar, libere o Foo antes de pegar o Bar. Mas você ainda precisa manter as regras de ordenação em mente. Em todos os segmentos que usam Foo e Bar, você deve adquirir e liberar mesma ordem:

  Enter Foo
Use Foo
Leave Foo
Enter Bar
Use Bar
Leave Bar

5) Se você lê apenas 99,9% do tempo e escreve 0.1% do tempo, não tente ser esperto. Você ainda tem que entrar na crítica mesmo quando estiver lendo. Isso é porque você não quer que uma gravação comece quando você está no meio de uma leitura.

6) Mantenha as seções críticas granulares. Cada seção crítica deve proteger um recurso, não vários recursos. Se você tornar as seções críticas muito "grandes", poderá serializar seu aplicativo ou criar um conjunto muito misterioso de deadlocks ou raças.


2 para resposta № 2

Use um wrapper C ++ ao redor da seção crítica que suporta RAII:

{
CriticalSectionLock lock ( mutex_ );

Do stuff...
}

O construtor para o bloqueio adquire o mutex e o destrutor libera o mutex mesmo se uma exceção for lançada.

Tente não ganhar mais do que um bloqueio em umtempo, e tente evitar chamar funções fora de sua classe enquanto segura bloqueios; isso ajuda a evitar a obtenção de bloqueios em lugares diferentes, então você tende a ter menos possibilidades de deadlocks.

Se você precisar ganhar mais de um bloqueio ao mesmo tempo, classifique os bloqueios pelo endereço deles e coloque-os em ordem. Dessa forma, vários processos ganham os mesmos bloqueios na mesma ordem sem coordenação.

Com uma porta IO, considere se você precisabloquear a saída ao mesmo tempo que a entrada - muitas vezes você tem um caso em que algo tenta escrever, então espera ler ou vice-versa. Se você tiver dois bloqueios, poderá obter um deadlock se um thread gravar, em seguida, ler e o outro ler e, em seguida, gravar. Muitas vezes, ter um thread que faz o IO e uma fila de pedidos resolve isso, mas isso é um pouco mais complicado do que apenas configurar chamadas com bloqueios, e sem muito mais detalhes eu não posso recomendá-lo.