【问题标题】:Scanf and Printf in OpenMPIOpenMPI 中的 Scanf 和 Printf
【发布时间】:2013-11-09 04:00:22
【问题描述】:

我正在使用 ANSI C 和 OpenMPI 库。

我有这个代码:

if(myRank == 0)
{
    printf("\n\tEnter bright: ");
    scanf("%d", &bright);
}

但是当我运行程序时,它首先等待按键 (scanf),然后是 printf。 我真的不知道发生了什么。

谢谢。

【问题讨论】:

  • 也许如果它首先等待按键之前它打印"\n\tEnter bright: ",那么你有一些其他代码正在调用另一个scanf(),或者类似的需要输入,并且会阻塞直到它发生。

标签: c openmpi


【解决方案1】:

这与 MPI 没有什么特别的关系,是一种非常正常的 Unix I/O 行为。标准输出流是行缓冲,这意味着除非在流中遇到新行或强制执行刷新操作,否则不会向底层 I/O 子系统发送任何内容。

比较以下内容:printf("asdasd");printf("asdasd\n");。在第一种情况下,asdasd 被附加到 stdout 流的缓冲区中,但由于那里没有新行,缓冲区没有被刷新,实际上没有任何东西发送到终端。在第二种情况下,asdasd 被附加到输出流中,然后新行的存在会导致自动刷新,因此您会立即看到 asdasd<new line>。正如 John Zwinck 所述,fflush(stdout); 可用于强制刷新流缓冲区。

请注意,如果您来自 Windows 背景,则标准输出没有行缓冲,printf("asdasd"); 确实会导致 adsasd 在没有后续显式刷新操作的情况下输出。但是,即使在 Windows 上,MPI 的 I/O 重定向机制也可能是行缓冲的。

【讨论】:

    【解决方案2】:

    我首先想知道以这种方式使用 scanf 是否有意义(将涉及多个进程——我们如何知道或假设它们中的任何一个都会连接到您的终端/键盘?)。但无论如何,打印后尝试冲洗:

    printf("\n\tEnter bright: ");
    fflush(stdout);
    scanf("%d", &bright);
    

    【讨论】:

    • 不客气。如果此答案解决了您的问题,请单击左侧的复选标记接受它。
    • 大多数 MPI 实现将 mpirun/mpiexec 的 IO 重定向到 0 级的标准输入和输出,因此 if (rank == 0) { scanf(); } 非常有意义。一个问题是这种行为不是由标准强加的,因此是不可移植的。
    猜你喜欢
    • 2015-02-12
    • 2017-01-07
    • 1970-01-01
    • 2017-11-26
    • 2021-12-04
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多