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

C语言线程池场景下如何将临时char*存入struct实现永久存储

ftw回调传递路径到线程池时临时变量异常问题

我正在实现一个线程池,目前遇到较大困难:ftw的OnOpen函数中获取的文件路径是临时实例,我需要将其更久地存储,但不允许对每个处理的文件路径都执行malloc操作。
我当前的代码尝试避免OnOpen给线程传递临时数据,但程序在执行memcpy时崩溃,我不清楚崩溃的原因。我希望能够避免临时变量被修改导致数据异常,同时不需要额外创建char*数组执行memcpy操作。
我当前的代码如下:

typedef struct Task{
    void (*taskFunc)(char*);
    char* arg;
} Task;

void HashFunc(char* arg)
{
    pthread_mutex_lock(&lock);
    printf("%s\n", arg);
    thingsDone++;
    pthread_mutex_unlock(&lock);
}

static int OnOpen(const char* path, const struct stat* sb, int flags)//也会传递文件夹路径
{
    if(strstr(path, ".exe") || strstr(path, ".cfg")) return 0;
    Task t = {
        .taskFunc = &HashFunc,
        .arg = path
    };
    memcpy(t.arg, path, strlen(path));
    while(taskCount == MAX_OPEN_FILE_HANDLES-1); //忙等待
    submitTask(t);
    return 0;
}

编辑:感谢大家的反馈,但还不完全符合我的需求。
下面补充我遇到问题的相关代码,即线程池以及task结构体的使用逻辑,方便大家更好地理解场景并给出解决方案:

void executeTask(Task* task) {task->taskFunc(task->arg);}

void* threadFunc(void* arg)
{
    Task task;
    while (!(doneSending==1 && thingsDone == thingsToDo))
    {
        pthread_mutex_lock(&lock);
        while (taskCount==0 && doneSending==0) {pthread_cond_wait(&condQueue, &lock);}
        task = taskQueue[0];
        for (int i = 0; i < taskCount-1; i++) {taskQueue[i] = taskQueue[i+1];}
        taskCount > 0 ? --taskCount : 0;
        pthread_mutex_unlock(&lock);
        if (doneSending==0 || thingsDone<thingsToDo) executeTask(&task);
        printf("%d, %d, %d, %d\n", taskCount, thingsDone, thingsToDo, doneSending);
    }
}

void submitTask(Task task)
{
    pthread_mutex_lock(&lock);
    taskQueue[taskCount++] = task;
    ++thingsToDo;
    pthread_mutex_unlock(&lock);
    pthread_cond_signal(&condQueue);
}

我的线程池包含8个线程,taskQueue的大小也为8。
我之前写过.arg = strcpy(temp, path)的逻辑,但由于temp是临时变量,导致hashFunc中打印的数据异常。
每个线程需要持有独立的Task结构体副本工作,避免互相干扰。

最终编辑:问题已解决,可行的实现代码如下:

volatile int taskIdx = 0, pathIdx = 0;

Task taskArray[MAX_OPEN_FILE_HANDLES];
char* pathQueue[MAX_OPEN_FILE_HANDLES];

void* threadFunc(void* args)
{
    Task task;
    while (!(doneSending==1 && taskIdx == pathIdx))
    {
        if (doneSending && taskIdx==pathIdx) break;
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&condArray, &lock);
        if (doneSending && taskIdx==pathIdx)
        {
            pthread_mutex_unlock(&lock);
            break;
        }
        task = taskArray[taskIdx];
        taskIdx = (taskIdx+1)%MAX_OPEN_FILE_HANDLES;
        pthread_mutex_unlock(&lock);
        executeTask(&task);
    }
}

void submitTask(Task t)
{
    pthread_mutex_lock(&lock);
    taskArray[pathIdx] = t;
    pathIdx = (pathIdx+1)%MAX_OPEN_FILE_HANDLES;
    pthread_cond_signal(&condArray);
    pthread_mutex_unlock(&lock);
}

static int OnOpen(const char* path, const struct stat* sb, int flags)
{
    if(flags != FTW_F || strstr(path, ".cfg") || strstr(path, ".exe") || strstr(path, ".vscode") || strstr(path, "anticheat") || strstr(path, "Makefile")) return 0;
    if (thingsToDo-thingsDone == MAX_OPEN_FILE_HANDLES) HashFunc((char*)path, thingsToDo++);
    else
    {
        Task t = {
            .taskFunc = &HashFunc,
            .filePath = strcpy(pathQueue[pathIdx], path)
        };
        submitTask(t);
    }
    return 0;
}

int main()
{
    pthread_mutex_init(&lock, NULL);
    pthread_cond_init(&condArray, NULL);
    for (int i=0; i<MAX_OPEN_FILE_HANDLES; i++)
    {
        if(pthread_create(&pool[i], NULL, &threadFunc, NULL) != 0) perror("pth_create");
        pathQueue[i] = calloc(MAX_PATH_LENGTH, sizeof(char));
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:06:04