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

