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

C语言多进程读取文件仅获1/3内容问题求助

C语言多进程文件读取异常问题解决方法

问题根源

多进程创建后,子进程会继承父进程的文件描述符和stdio流,但内核级的文件偏移量是所有共享同一文件描述符的进程共用的。当多个进程同时操作同一个文件时,任意一个进程的读取操作都会移动这个共享偏移量,导致负责读取完整文件的第一个进程被其他进程“截断”,最终只能读取到约1/3的内容。

解决办法

1. 让读取进程独占文件资源

确保只有负责读取的进程操作目标文件,其他进程继承文件描述符后立即关闭,避免干扰:

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

#define BUFFER_SIZE 1024

int main() {
    FILE *input = fopen("test.txt", "r");
    if (!input) {
        perror("fopen failed");
        exit(1);
    }

    for (int i = 0; i < 3; i++) {
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork failed");
            fclose(input);
            exit(1);
        } else if (pid == 0) {
            if (i != 0) {
                // 非读取进程直接关闭文件
                fclose(input);
                // 执行其他业务逻辑
                exit(0);
            }

            // 第一个进程读取完整文件
            char buffer[BUFFER_SIZE];
            size_t bytes_read;
            while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, input)) > 0) {
                // 处理读取内容,示例为输出到标准输出
                fwrite(buffer, 1, bytes_read, stdout);
            }
            fclose(input);
            exit(0);
        }
    }

    for (int i = 0; i < 3; i++) {
        wait(NULL);
    }
    fclose(input);
    return 0;
}

2. 让读取进程独立打开文件

避免进程间共享文件描述符,由读取进程自行打开文件,确保拥有独立的文件偏移量:

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

#define BUFFER_SIZE 1024

int main() {
    for (int i = 0; i < 3; i++) {
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork failed");
            exit(1);
        } else if (pid == 0) {
            if (i == 0) {
                // 读取进程独立打开文件
                FILE *input = fopen("test.txt", "r");
                if (!input) {
                    perror("fopen failed");
                    exit(1);
                }
                char buffer[BUFFER_SIZE];
                size_t bytes_read;
                while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, input)) > 0) {
                    fwrite(buffer, 1, bytes_read, stdout);
                }
                fclose(input);
            }
            // 其他进程执行自身逻辑
            exit(0);
        }
    }

    for (int i = 0; i < 3; i++) {
        wait(NULL);
    }
    return 0;
}

3. 多进程协作读取时加锁(如果需要)

如果必须多个进程同时操作文件,使用文件锁保证同一时间只有一个进程访问文件,避免偏移量混乱:

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

#define BUFFER_SIZE 1024

int main() {
    int fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("open failed");
        exit(1);
    }

    for (int i = 0; i < 3; i++) {
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork failed");
            close(fd);
            exit(1);
        } else if (pid == 0) {
            if (i == 0) {
                char buffer[BUFFER_SIZE];
                ssize_t bytes_read;
                // 加独占锁
                if (flock(fd, LOCK_EX) == -1) {
                    perror("flock failed");
                    close(fd);
                    exit(1);
                }
                // 读取文件
                while ((bytes_read = read(fd, buffer, BUFFER_SIZE)) > 0) {
                    write(STDOUT_FILENO, buffer, bytes_read);
                }
                // 释放锁
                flock(fd, LOCK_UN);
            }
            close(fd);
            exit(0);
        }
    }

    for (int i = 0; i < 3; i++) {
        wait(NULL);
    }
    close(fd);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:23:12