一组线程同时调用 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 循环的时间超出了必要时间。