Os exemplos dados de por que condições de corrida ocorrem são que uma thread pode acessar memória que não é a versão mais recente porque outra thread pode tê-la modificado ou estar modificando-a ao mesmo tempo. Portanto, protegemos áreas de memória com primitivas de sincronização ou variáveis atômicas. O que eu quero saber é se a seguinte afirmação é verdadeira:
Sempre que mais de um thread acessa o mesmo local de memória de um único processo, ele DEVE, em todas as circunstâncias, ser sincronizado explicitamente.
Por explicitamente, quero dizer coisas como um mutex ou uma variável atômica, uma barreira ou algo assim. É esse o caso? A razão pela qual pergunto isso é porque, quando são dados exemplos de por que precisamos de sincronização entre threads, sempre se trata de threads acessando uma área da memória em um curto período de tempo, e a explicação geralmente é algo como "não sabemos se a Thread 2 verá o valor escrito pela Thread 1". No entanto, considere o seguinte:
int some_global_var = 0; // INITIALIZED BEFORE STARTUP
Thread 1:
some_global_var = 1;
Thread 2:
sleep_for(/* 5 days */);
print("%d", some_global_var);
Esta ainda é uma condição de corrida e deve ser sincronizada, certo? Em outras palavras, a regra é simples: se for acessado por mais de uma thread em um processo, sem ifs, ands ou buts, você DEVE usar variável atômica ou mutex?
A definição de uma condição de corrida é precisa e não invoca nenhum componente de tempo. Sem primitivas de sincronização para impedi-las, condições de corrida podem ocorrer e você terá um comportamento indefinido, ponto final.