c - 为什么没有fopen / fprintf的竞争条件[重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

我试图模拟一个竞争条件(这是一个正确的术语?),以便以后用信号量修复它。

我有一个master.c过程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
    for(int i = 0; i < 100; ++i)
    {
        if (fork() == 0)
        {
            char str[12];
            sprintf(str, "%d", i%10);
            execl("./slave", "slave", str, (char *)0);
        }
    }

    return 0;
}

以及打印到文件中的slave.c进程:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    FILE *p_file;
    p_file = fopen("out.txt", "a");
    for (int i = 0; i < 100; ++i)
    {
        usleep(100000); // I tried using this but it changes nothing
        fprintf(p_file, "%s", argv[1]);
    }
    fprintf(p_file, "\n");

    return 0;
}

输出文件out.txt看起来像这样:https://pastebin.com/nU6YsRsp

订单是“随机的”,但由于某种原因没有数据损坏。这是为什么?

c linux fork exec fopen
1个回答
2
投票

因为stdio在写入文件时默认使用缓冲输出,并且您在每个进程中打印的所有内容都适合单个缓冲区。缓冲区在进程退出之前不会被刷新,然后它被写为单个write()调用,该调用足够小,可以原子方式写入文件。

在每个fflush(p_file);之后调用fprintf(),你会得到更多的混合结果。或者调用setvbuf()来禁用缓冲。

© www.soinside.com 2019 - 2024. All rights reserved.