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

基于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开始计数

实现思路

  1. 先做参数合法性校验:检查输入参数数量、目标目录是否存在、总文件数和线程数是否为正整数
  2. 任务均分:计算每个线程的基础处理文件数,剩余文件分配给前N个线程,保证负载均衡
  3. 线程独立参数:给每个线程传递独立的任务区间、目标目录等参数,不使用全局变量,避免线程安全问题
  4. 线程内独立完成文件创建全流程:每个线程自己负责构造文件名、打开文件、写入内容、关闭文件,完全独立无共享资源
  5. 主线程等待所有工作线程执行完毕后再退出

修改后完整代码

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:45:04