5

我创建了这个测试 Matlab 脚本文件:

numbers = [29 37 44 54 62];

for i=1:length(numbers)
    fprintf('%d\n', numbers(i));
end

fprintf('***\n');

matlabpool local 5;
parfor i=1:length(numbers)
    fprintf('%d\n', numbers(i));
end % image loop
fprintf('***\n')
for i=1:length(numbers)
    fprintf('%d\n', numbers(i));
end
matlabpool close;

fprintf('***\n');

for i=1:length(numbers)
    fprintf('%d\n', numbers(i));
end

当我运行它时,我始终得到以下输出:

29
37
44
54
62
***
112
111
107
117
115
***
29
37
44
54
62
***
29
37
44
54
62

块内打印看似随机fprintfparfor一组数字,但它们始终相同(112、111、107、117、115)。知道为什么会这样吗?

更新

有趣的是,这只有在我从命令行运行脚本时才会发生:

matlabR2012b -nodesktop -nosplash -nodisplay -r "run parfortest.m; exit"

如果我首先打开一个 Matlab 会话并在parfortest那里运行,那么数字会正确打印。

4

3 回答 3

2

这特别是运行问题,而不是 nodesktop 问题。要验证这一点,您可以尝试

>> run parfortest.m

从 MATLAB 桌面,您会发现相同的输出。

虽然这不是这样的解决方案;如果你省略运行,只需使用

>> parfortest

错误的输出将被纠正。

于 2013-06-05T17:16:44.173 回答
1

我也可以在 OS X、R2012b 上复制它。在mexmexPrintf不是线程安全的。看到这个fprintf如果 Matlab依赖mexPrintf- 或类似的代码 - 在引擎盖下,我不会感到惊讶。如果你把你的脚本变成一个函数——只要放在function parfortest第一行——问题就消失了,所以它也可能是一个范围问题。

编辑:尝试打印五个以上的数字,比如十二个。现在使用char将这些值转换为 ASCII 字符。看起来,在parfor循环fprintf中打印出您通过终端命令运行的文件的路径(某种形式的parfortest.m随机顺序 - 我运行文件~/Desktop/parfortest.m并将数字从转换为fprintf我得到的字符D/~ksepotap/frroetst.m)。如果您尝试打印比路径长度更多的值,则会出现错误。除了将您的脚本变成一个函数之外,我找不到解决方法(无论如何这是个好主意)。绝对看起来像一个错误。

于 2013-06-05T16:43:59.367 回答
0

我猜你不能真正并行写入文件。或者在这种情况下输出屏幕,因为 fprintf("text") 意味着 fprintf(1,"text") 其中 1 是输出屏幕的文件 ID。

该文件现在正在被多个进程修改,这是一个问题,因为在其他操作开始之前未刷新使用的缓冲区,并且行为将不稳定。

也许这个链接会有所帮助。

于 2013-06-05T16:38:45.243 回答