V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
qemu32
V2EX  ›  Linux

Linux c 编程问题请教,父进程如何保证在读取子进程写入的文件之前子进程已经写入完毕?

  •  
  •   qemu32 · 2022-09-16 13:46:34 +08:00 · 1769 次点击
    这是一个创建于 836 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    	pid = fork();
    
    	if (!pid) {
    		execvp(args[0], args); // 这里会创建一个路径为 path 的文件,并且会写入一些数据。
    	}
    
    	wait(&wstatus);
    
    	fd = open(path, O_RDONLY); // 读取子进程创建的文件
        	while ((n = read(fd, buf, BUFSIZ)) > 0)
    		if (write(connfd, buf, n) != n)
    			printf("write error\n");
                
    

    这段代码先 fork 一个子进程,子进程创建并写入一些数据到一个文件。

    父进程通过 wait 等待子进程执行完毕,然后 open 并开始读取子进程写入的文件。

    这段代码有一个问题,就是有时子进程明明写入了一些数据到文件,但父进程却读取不到任何数据,就像子进程只是创建了一个空文件一样,如果在 wait 后加一个 sleep(1)就没有这种情况,请问如何保证子进程写入文件完毕后父进程才开始读取?

    14 条回复    2022-09-16 23:09:50 +08:00
    BingoXuan
        1
    BingoXuan  
       2022-09-16 14:03:58 +08:00
    试一下子进程写入文件加上 O_SYNC 。我觉得这种情况不应该先创建文件,通过 fork 共享文件不会更好吗?
    nightwitch
        2
    nightwitch  
       2022-09-16 14:05:31 +08:00 via Android
    给文件加锁,父进程 flush 以后再解锁
    qemu32
        3
    qemu32  
    OP
       2022-09-16 14:08:10 +08:00
    @BingoXuan 感谢回复,子进程不是我的项目,不能去改子进程的代码,其实我是想去开发一个分布式编译系统,这个子进程就是 gcc ,父进程是需要把 gcc 编译生成的可重定位目标文件读取出来再通过网络传给客户端。
    qemu32
        4
    qemu32  
    OP
       2022-09-16 14:09:07 +08:00
    @nightwitch 感谢回复,能说的再具体一点吗?
    codehz
        5
    codehz  
       2022-09-16 14:14:29 +08:00
    (linux 的话,可以要求 gcc 生成文件到 /dev/stdout 的,然后你直接 pipe 一下就可以接收了
    JohnBull
        6
    JohnBull  
       2022-09-16 14:15:58 +08:00
    你是不是还有别的子进程?你确定 wait 到的一定是你刚才创建的进程吗?
    你改用 waitpid 指定下 pid 试试呢
    codehero
        7
    codehero  
       2022-09-16 14:17:55 +08:00
    是 gcc 的话用 waitpid 等 gcc 结束再读应该可以
    qemu32
        8
    qemu32  
    OP
       2022-09-16 14:19:07 +08:00
    @codehz 也是一种办法
    qemu32
        9
    qemu32  
    OP
       2022-09-16 14:19:53 +08:00
    @nhf0424 确实,我这里是会有好多个子进程,应该就是这个原因。
    qemu32
        10
    qemu32  
    OP
       2022-09-16 14:24:04 +08:00
    @nhf0424 改用 waitpid 就正常了,结贴
    julyclyde
        11
    julyclyde  
       2022-09-16 17:33:42 +08:00
    不容易判断消息的边界 /结束
    这正是我在 /t/878224 反对使用文件做 ipc 的原因
    elechi
        12
    elechi  
       2022-09-16 19:21:41 +08:00
    写完文件 flush ,确保文件写入完成
    JohnBull
        13
    JohnBull  
       2022-09-16 23:05:11 +08:00
    @julyclyde 可以用文件锁解决
    DeWjjj
        14
    DeWjjj  
       2022-09-16 23:09:50 +08:00
    写进缓存,然后读取有天然保护。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   990 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:43 · PVG 04:43 · LAX 12:43 · JFK 15:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.