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
相关产品推荐
相关产品推荐

