Em um programa C multithread Windows/Linux, se uma unsigned int
variável global for acessada por três threads sem nenhuma sincronização, onde
- Thread 1 escreve o valor 0
- O thread 2 grava o valor 0xFFFFFFFF
- Thread 3 lê o valor
Pergunta
É possível que o Thread 3 recupere um valor parcial, digamos 0x0000FFFF da variável global?
Sempre presumi que, se um unsigned int
estiver alinhado corretamente, uma operação de gravação é atômica; portanto, nesse caso, o Thread 3 sempre seria 0 ou 0xFFFFFFFF.
Você esqueceu um caso muito provável: o thread 3 não lê o valor, usando um valor lido anteriormente.
A sincronização não apenas evita leituras/gravações parciais; ele também informa à CPU e ao compilador que o valor pode ser alterado por outro thread. Eles podem e assumem que isso não acontecerá se não houver sincronização, portanto, um valor em cache pode ser usado ou a leitura pode ser otimizada, etc.
(Estou usando o termo "sincronização" vagamente aqui.)
Dada essa possibilidade, é discutível se você pode terminar com 0000FFFF ou não.
Seu programa contém uma corrida de dados, portanto seu comportamento é indefinido no que diz respeito a C. A princípio sim, a thread 3 poderia observar um valor diferente do valor inicial da variável e dos valores escritos pelas threads 1 e 2, sem limite.
É um erro tentar prever o comportamento de um programa C com base em seu próprio modelo de como seu código-fonte corresponde a instruções de nível inferior. E você não precisa tentar isso se escrever um código cujo comportamento é bem definido pela especificação da linguagem C.
No entanto, pode ser que sua implementação C específica nunca exiba o tipo de cisalhamento sobre o qual você pergunta nas circunstâncias que você descreve, mas mesmo assim, isso não torna seu código atrevido seguro. Seu comportamento ainda é indefinido e ainda pode apresentar mau comportamento na prática. Como o thread 3 nunca observando nenhuma das outras duas threads, por exemplo.