我有两个程序产生多个线程并将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;
}
二分之二:
#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;
}
程序只需调用printf()
,输出就不会出现乱码。
但是,对于第二个程序,两次调用printf()
,输出会出现乱码。
对于第二个程序,从来没有干扰字符串序列;从来没有类似hhhhellloohello...
的东西。然而,不同的输出字符串之间存在混淆;一种可能性的排列:
hello 27hello 62hello 52hello 50hello 10world 62...
作为一个例子。
我认为#pragma omp critical
会在pragma
之后断言互斥,直到并行块结束。但事实似乎并非如此。
#pragma omp critical
仅适用于紧随其后的声明吗?
任何有关出现这种情况的见解都会很棒。 艾萨克
答案 0 :(得分:4)
与#pragma omp critical
{
printf("hello %d", ID);
printf("world %d\n", ID);
}
一样,#pragma omp critical
仅限于下一行,除非您也将其设为块。
如果您不想使用交错输出,请使用另一组花括号:
$list = file_get_contents('http://example.com/list/json');
$items = json_decode($list, true);
答案 1 :(得分:3)
可能是因为POSIX要求单个I / O函数调用是线程安全的,但不需要在单独的函数调用之间进行锁定。该规范的相关部分隐藏在页面上:
flockfile()
funlockfile()
ftrylockfile()
规范的相关部分接近结尾:
所有引用(
FILE *
)对象的函数,除了名称以_unlocked
结尾的对象外,其行为应该像在内部使用flockfile()
和funlockfile()
一样获得所有权这些(FILE *
)个对象。
这意味着,例如,printf()
必须在输入时执行(相当于)flockfile(stdout)
,在退出时必须(等效于)funlockfile(stdout)
。
这与您在OMP代码中看到的完全一致。单个调用printf()
的文本不与任何其他并发调用交错,但printf()
调用的序列在线程之间交错。
答案 2 :(得分:0)
从here,您可以看到应该由一个线程一次运行的代码应放入代码块中。
添加名称也是一个好主意,这样如果你使用多个这样的指令就不会发生冲突,