基于C语言Linux系统调用实现多线程批量创建bin文件的问题咨询
C语言多线程批量创建文件实现调整方案
需求回顾
- 输入参数:目标目录路径、总文件数
f、线程总数t - 输出文件命名规则:
file_<id>.bin,id取值范围为0~f-1,全局唯一 - 任务分配规则:t个线程每个大致创建
f/t个文件 - 要求使用Linux原生
open()/close()/write()等系统调用实现
现有代码核心问题
- 线程使用逻辑错误:每个文件单独创建线程并立刻阻塞等待线程结束,实际为串行执行,无并发能力,也未按指定线程数分配任务
- 文件名构造错误:字符串拷贝逻辑直接覆盖前缀,未按要求生成
file_<id>.bin格式,也未拼接目标目录路径 - 全局文件描述符线程不安全:多线程并发时会互相覆盖值,导致读写错误
- 参数逻辑缺失:未接收线程数
t参数,也无基础的参数合法性校验 - 索引范围错误:要求id从0开始,现有代码从1开始计数
实现思路
- 先做参数合法性校验:检查输入参数数量、目标目录是否存在、总文件数和线程数是否为正整数
- 任务均分:计算每个线程的基础处理文件数,剩余文件分配给前N个线程,保证负载均衡
- 线程独立参数:给每个线程传递独立的任务区间、目标目录等参数,不使用全局变量,避免线程安全问题
- 线程内独立完成文件创建全流程:每个线程自己负责构造文件名、打开文件、写入内容、关闭文件,完全独立无共享资源
- 主线程等待所有工作线程执行完毕后再退出
修改后完整代码
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <limits.h> // 线程参数结构体:每个线程独立的任务信息 typedef struct { const char* base_dir; int start_id; int end_id; } ThreadArg; int isDirectoryExists(const char *path); void *thread_work(void *ptr); int main(int argc, char *argv[]) { // 参数校验 if (argc != 4) { printf("用法:%s <目标目录> <总文件数f> <线程数t>\n", argv[0]); return 1; } const char* dir = argv[1]; int f = atoi(argv[2]); int t = atoi(argv[3]); if (f <= 0 || t <=0) { printf("总文件数和线程数必须为正整数\n"); return 1; } // 线程数不能超过文件数,最多每个线程创建1个文件 if (t > f) t = f; if (!isDirectoryExists(dir)) { printf("目录不存在:%s\n", dir); return 1; } pthread_t* threads = malloc(t * sizeof(pthread_t)); ThreadArg* args = malloc(t * sizeof(ThreadArg)); if (!threads || !args) { perror("内存分配失败"); return 1; } // 计算任务分配 int per_thread = f / t; int remain = f % t; int cur_id = 0; for (int i = 0; i < t; i++) { args[i].base_dir = dir; args[i].start_id = cur_id; // 前remain个线程多处理1个文件 args[i].end_id = cur_id + per_thread + (i < remain ? 1 : 0) - 1; cur_id = args[i].end_id + 1; // 创建线程 if (pthread_create(&threads[i], NULL, thread_work, &args[i]) != 0) { perror("线程创建失败"); return 1; } } // 等待所有线程执行完毕 for (int i = 0; i < t; i++) { pthread_join(threads[i], NULL); } printf("所有文件创建完成,共%d个文件,使用%d个线程\n", f, t); free(threads); free(args); return 0; } // 线程工作函数:负责创建[start_id, end_id]范围内的所有文件 void *thread_work(void *ptr) { ThreadArg* arg = (ThreadArg*)ptr; char file_path[PATH_MAX]; char write_buf[32]; int buf_len; for (int id = arg->start_id; id <= arg->end_id; id++) { // 构造完整文件路径 snprintf(file_path, sizeof(file_path), "%s/file_%d.bin", arg->base_dir, id); // 打开文件 int fd = open(file_path, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (fd < 0) { printf("创建文件失败:%s,错误:%s\n", file_path, strerror(errno)); continue; } // 写入测试内容(可根据需求修改写入逻辑) buf_len = snprintf(write_buf, sizeof(write_buf), "file id: %d\n", id); write(fd, write_buf, buf_len); close(fd); } return NULL; } int isDirectoryExists(const char *path) { struct stat stats; if (stat(path, &stats) != 0) return 0; return S_ISDIR(stats.st_mode) ? 1 : 0; }
编译运行方法
编译命令:gcc -o batch_create batch_create.c -lpthread
运行示例:./batch_create ./test_dir 100 4,代表在./test_dir目录下创建100个文件,使用4个线程。
内容的提问来源于stack exchange,提问作者parth parashar
相关产品推荐
相关产品推荐

