C 防止竞争条件的printf

C 防止竞争条件的printf,c,multithreading,openmp,race-condition,C,Multithreading,Openmp,Race Condition,在这个示例代码中,我从I=0到I=n进行求和,然后将结果添加到自身k次,其中k是线程数。我故意这样做,没有造成竞争条件的临界(围绕printf和ans+=ans)。然而,令我惊讶的是,没有发生任何比赛条件: int summation_with_operation_after_it_wrong1(int n, int k) { int ans = 0; #pragma omp parallel firstprivate(n) num_threads(k)

在这个示例代码中,我从
I=0
I=n
进行求和,然后将结果添加到自身
k
次,其中
k
是线程数。我故意这样做,没有造成竞争条件的
临界
(围绕
printf
ans+=ans
)。然而,令我惊讶的是,没有发生任何比赛条件:

int summation_with_operation_after_it_wrong1(int n, int k) {
        int ans = 0;
        #pragma omp parallel firstprivate(n) num_threads(k)
        {
                int i; /* Private */
                #pragma omp for schedule(dynamic) reduction(+:ans)
                for (i = 0; i < n; i++) {
                        ans += i;
                }
                printf("Thread %d ans=%d\n", omp_get_thread_num(), ans);
                ans += ans;    
        }
        return ans;
}
然而,我确实注意到了一些奇怪的事情<代码>ans
始终为45,而不是

Thread 3 ans=45
Thread 0 ans=90
Thread 2 ans=180
Thread 1 ans=360
720
使用
临界时
。因此,我将
printf
移动到
ans+=ans
之后,看看它在做什么,让我惊讶的是,预测的比赛条件一直在发生

Thread 3 ans=90
Thread 1 ans=135
Thread 2 ans=90
Thread 0 ans=135
135
所以。。。
printf
如何防止竞争条件?那么这个总数是怎么变成720的呢?我在这里完全迷路了。

printf()
是一个非常昂贵的调用,使用它改变比赛条件计时也就不足为奇了。查看发生了什么的更好的选择是(提前)创建一个数组来存储结果,并让每个线程将其结果存储到当前正在执行打印的数组中;然后在所有工作完成后执行实际的
printf()。查看发生了什么的更好的选择是(提前)创建一个数组来存储结果,并让每个线程将其结果存储到当前正在执行打印的数组中;然后在所有工作完成后执行实际的
printf()。查看发生了什么的更好的选择是(提前)创建一个数组来存储结果,并让每个线程将其结果存储到当前正在执行打印的数组中;然后在所有工作完成后执行实际的
printf()。查看发生了什么的更好的选择是(提前)创建一个数组来存储结果,并让每个线程将其结果存储到当前正在执行打印的数组中;然后在所有工作完成后执行实际的
printf()

如果多个线程不同步地写入同一内存 单元,包括由于所述原子性考虑而导致的情况 在上面,则会发生数据竞争。类似地,如果至少有一个线程 从内存单元读取数据,并且至少有一个线程在没有 同步到同一内存单元,包括由于 原子性考虑如上所述,则会发生数据竞争。 如果发生数据竞争,则程序的结果未指定。

您注意到的内容与粗体字的陈述完全一致。事实上,由于包含数据竞争的程序中的行为是未指定的,因此争论特定输出为何来自给定运行是毫无意义的。特别是,在
ans+=ans
命令之前插入
printf
时,您只是碰巧获得了
720
,并且不能保证您总是会遇到相同的行为。

最新版本的第1.4节规定了竞争条件的结果(强调我的):

如果多个线程不同步地写入同一内存 单元,包括由于所述原子性考虑而导致的情况 在上面,则会发生数据竞争。类似地,如果至少有一个线程 从内存单元读取数据,并且至少有一个线程在没有 同步到同一内存单元,包括由于 原子性考虑如上所述,则会发生数据竞争。 如果发生数据竞争,则程序的结果未指定。

您注意到的内容与粗体字的陈述完全一致。事实上,由于包含数据竞争的程序中的行为是未指定的,因此争论特定输出为何来自给定运行是毫无意义的。特别是,在
ans+=ans
命令之前插入
printf
时,您只是碰巧获得了
720
,并且不能保证您总是会遇到相同的行为。

最新版本的第1.4节规定了竞争条件的结果(强调我的):

如果多个线程不同步地写入同一内存 单元,包括由于所述原子性考虑而导致的情况 在上面,则会发生数据竞争。类似地,如果至少有一个线程 从内存单元读取数据,并且至少有一个线程在没有 同步到同一内存单元,包括由于 原子性考虑如上所述,则会发生数据竞争。 如果发生数据竞争,则程序的结果未指定。

您注意到的内容与粗体字的陈述完全一致。事实上,由于包含数据竞争的程序中的行为是未指定的,因此争论特定输出为何来自给定运行是毫无意义的。特别是,在
ans+=ans
命令之前插入
printf
时,您只是碰巧获得了
720
,并且不能保证您总是会遇到相同的行为。

最新版本的第1.4节规定了竞争条件的结果(强调我的):

如果多个线程不同步地写入同一内存 单元,包括由于所述原子性考虑而导致的情况 在上面,则会发生数据竞争。同样,我
Thread 3 ans=90
Thread 1 ans=135
Thread 2 ans=90
Thread 0 ans=135
135