一组线程同时调用 check_bad_array() 以检查数组 data_array 中是否存在任何“错误”元素。每个线程检查数组的不同部分。如果线程发现某个元素有错误,它会将全局共享变量 is_bad 的值设置为真。
20 volatile int is_bad = 0; ... 100 /* 101 * Each thread checks its assigned portion of data_array, and sets 102 * the global flag is_bad to 1 once it finds a bad data element. 103 */ 104 void check_bad_array(volatile data_t *data_array, unsigned int thread_id) 105 { 106 int i; 107 for (i=my_start(thread_id); i<my_end(thread_id); i++) { 108 if (is_bad) 109 return; 110 else { 111 if (is_bad_element(data_array[i])) { 112 is_bad = 1; 113 return; 114 } 115 } 116 } 117 }
第 108 行中对 is_bad 的读取与第 112 行中对 is_bad 的写入之间存在数据争用。但是,该数据争用不影响最终结果的正确性。
is_bad 的初始值为 0。当线程更新 is_bad 时,它们会为其分配值 1。也就是说,这些线程会在 is_bad 的同一内存字节的同一位中存储 1。在当前的体系结构中,可以放心地认为这些存储是原子操作。因此,某个线程读取 is_bad 时,读取的值要么为 0,要么为 1。如果某个线程在 is_bad(第 108 行)被分配值 1 之前对其进行检查,则该线程会继续执行 for 循环。在此期间,如果另一个线程也将值 1 分配给 is_bad(第 112 行),这并不会改变最终结果。这仅仅意味着该线程执行 for 循环的时间超出了必要时间。