为什么在一次编译指示出现关键操作后多次调用printf会产生乱码的输出?

iza*_*aak 1 c c++ openmp

我有两个产生多个线程并打印hello <TID> world <TID>到stdout的程序。第一个在一个函数中打印它:

#include <omp.h>                                                
#include <stdio.h>                                               
int main() {                               
#pragma omp parallel                       
  {                                        
    int ID = omp_get_thread_num();         
#pragma omp critical                                  
    printf("hello  %d world %d\n", ID, ID);                                  
  }      
  return 0;                                  
}    
Run Code Online (Sandbox Code Playgroud)

二分之二:

#include <omp.h>                                                  
#include <stdio.h>                                           
int main() {                               
#pragma omp parallel                       
  {                                        
    int ID = omp_get_thread_num();         
#pragma omp critical                       
    printf("hello  %d", ID);             
    printf("world %d\n", ID);                                                
  }  
  return 0;                                      
}      
Run Code Online (Sandbox Code Playgroud)

只需对调用一次,程序printf()就不会出现乱码。但是,在第二个程序中,对的两次调用printf()使输出出现乱码。在第二个程序中,永远不会有乱码干扰字符串序列。从来没有这样的东西hhhhellloohello...。但是,不同的输出字符串之间存在乱码;可能性的排列:

hello  27hello  62hello  52hello  50hello  10world 62...
Run Code Online (Sandbox Code Playgroud)

举个例子。

我以为在并行化块结束之前#pragma omp critical会断言相互排斥pragma。但这似乎并非如此。是否#pragma omp critical只适用于声明紧随其后呢?

为什么会发生这种情况的任何见解都是很好的。伊扎克

And*_*dyG 5

#pragma omp parallel#pragma omp critical仅限于下一行,除非你也使它成为一个块。

如果不想交错输出,请使用另一组花括号:

#pragma omp critical                       
{
    printf("hello  %d", ID);             
    printf("world %d\n", ID); 
}
Run Code Online (Sandbox Code Playgroud)