如果从不读取值,让多个线程写入同一个 bool 是否安全?

Der*_*ton 4 c# concurrency multithreading thread-safety

我想出了一个有趣的情况。我有一个 bool 变量,然后我希望多个线程执行自己的独立任务,然后根据线程的结果标记该 bool。此变量永远不会被任何线程读取,并且在所有写入测试完成之前永远不会使用。像这样:

public bool F(){
    bool flag = false;
    Parallel.ForEach(list, element => 
    {
        bool result = // Do independent work here;
        if (result) flag = true;
    });
    return flag;
}
Run Code Online (Sandbox Code Playgroud)

Notice how I never read flag inside my Parallel.ForEach. But what could happen is having multiple threads attempting to write true to flag (but never false). Is it safe to do this?

das*_*ght 5

Yes, this is absolutely safe to do. The only thing that could happen is multiple threads writing true into flag concurrently, so you don't know which thread would end up overriding what result, but the end result is going to be the same.

By the time you read the flag all the writing has finished, and you never attempt to write anything except true into flag. Hence, the only two situations that you could see are as follows:

  • None of the threads write anything into flag - in this case the flag would remain false, or
  • One or more threads write true into the flag - in this case the flag would be set to true.

If you want to avoid this situation altogether, and perhaps save some execution time, you could do this:

return list.AsParallel().Any(element => {
    bool result = // Do independent work here
    ...
    return result;
});
Run Code Online (Sandbox Code Playgroud)

This code will not result in equivalent execution path, because the execution may stop early if one of the threads returns true. If this is not desirable, keeping your ForEach approach is fine, too.