You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fork子进程文件复制正常,父进程生成空文件的作业问题求助

Hey there! Let's figure out why your parent process's mainlog.txt is ending up empty. Based on your code snippet and the test file content, I can spot a couple of key issues causing this:

Key Issues & Fixes

1. Shared File Resources Conflicting After fork()

When you open files before calling fork(), both the parent and child processes get copies of the user-space FILE structs, but they share the underlying kernel file descriptors and file offset pointers. This leads to messy behavior:

  • If the child reads first, it moves the shared kernel file offset, so the parent might start reading from the end of the file (hence nothing to write).
  • C's buffered I/O adds another layer of confusion—each process has its own buffer, so data read by one might not be visible to the other.

Fix Option 1: Open Files After Fork (Cleanest Approach)

Have each process open its own file handles after forking. This completely avoids shared resource conflicts:

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

int main(){ 
    int c1; 
    char str[100]; 

    c1 = fork(); 
    if(c1 == 0){
        // Child process: handle lines starting with '1'
        FILE *fp_in = fopen("test.txt","r");
        FILE *fp_out = fopen("child1log.txt","w");
        
        // Always check if file opens succeeded!
        if(!fp_in || !fp_out){
            perror("Failed to open file");
            exit(1);
        }

        while(fgets(str, sizeof(str), fp_in) != NULL){
            if(str[0] == '1'){
                fputs(str, fp_out);
            }
        }

        fclose(fp_in);
        fclose(fp_out);
        exit(0); // Exit child to avoid running parent code
    } else if(c1 > 0){
        // Parent process: handle lines starting with '0'
        FILE *fp_in = fopen("test.txt","r");
        FILE *fp_out = fopen("mainlog.txt","w");
        
        if(!fp_in || !fp_out){
            perror("Failed to open file");
            exit(1);
        }

        while(fgets(str, sizeof(str), fp_in) != NULL){
            if(str[0] == '0'){
                fputs(str, fp_out);
            }
        }

        fclose(fp_in);
        fclose(fp_out);
        wait(NULL); // Wait for child to finish to avoid zombies
    } else {
        perror("Fork failed");
        exit(1);
    }
    return 0;
}

2. Missing Critical Guardrails in Your Original Code

If you must open files before forking, you need to fix the buffer and offset issues:

  • Call fflush(fp1) in both parent and child right after forking to sync user-space buffers with the kernel.
  • Use fseek(fp1, 0, SEEK_SET) to reset the file pointer to the start for each process.
  • Always check fopen() return values—you might be silently failing to open a file.
  • Have the child call exit(0) after its work, so it doesn't execute the parent's code path.
  • Parent must call wait() to ensure the child finishes its I/O before exiting.

Quick Test Tip

After running your fixed code, verify:

  • child1log.txt contains 1 text to be copied to child1.
  • mainlog.txt contains 0 text to be copied to parent

内容的提问来源于stack exchange,提问作者Elvyn Liew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:07:10