我想使用条件变量最多启动N个线程来处理一个大目录(1M个文件)中的所有文件。
该代码似乎可以正常工作,但一段时间后,它将在主线程中阻塞。在令人沮丧的代码下面:
void* run(void* ctx)
{
clientCtx* client = (clientCtx*)ctx;
printf("New file from thread %d: %s\n", client->num, client->filename);
free(client->filename);
pthread_mutex_lock(&clientFreeMutex);
client->state = IDLE_STATE;
pthread_cond_signal(&clientFreeCond);
printf("Thread %d is free\n", client->num);
pthread_mutex_unlock(&clientFreeMutex);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t client[MAX_CLIENT] = {0};
clientCtx ctx[MAX_CLIENT] = {0};
DIR* directory = NULL;
struct dirent* element = NULL;
/* Initialize condition variable for max clients */
pthread_mutex_init(&clientFreeMutex, NULL);
pthread_cond_init(&clientFreeCond, NULL);
/* Initialize contexts for clients */
for (int cnt = 0; cnt < MAX_CLIENT; cnt ++)
{
ctx[cnt].state = IDLE_STATE;
ctx[cnt].num = cnt;
}
directory = opendir(argv[1]);
while((element = readdir(directory)) != NULL)
{
pthread_mutex_lock(&clientFreeMutex);
int cnt;
for (cnt = 0; cnt < MAX_CLIENT; cnt++)
{
if(ctx[cnt].state == IDLE_STATE)
{
ctx[cnt].filename = strdup(element->d_name);
ctx[cnt].state = BUSY_STATE;
pthread_create(&client[cnt], NULL, run, &(ctx[cnt]));
break;
}
}
/* No free client */
if (cnt == MAX_CLIENT)
{
printf("No free thread. Waiting.\n");
pthread_cond_wait(&clientFreeCond, &clientFreeMutex);
}
pthread_mutex_unlock(&clientFreeMutex);
}
closedir(directory);
exit(EXIT_SUCCESS);
}
出什么问题了?谢谢您的帮助:)
答案 0 :(得分:0)
警告您在单独的线程中使用 readdir 的值,而没有针对多线程的任何保护,因此(尝试) printf client->file->d_name
如果您在修改保存结果的主线程中同时执行 readdir ,则这具有不确定的行为。
例如,您需要在{em> main 中保存element->file->d_name
的 strdup ,并将该字符串保存在 clientCtx 中,而不是struct dirent *
,当然要在 run
请注意, main 末尾缺少 closedir ,即使在这种情况下,这也不是真正的问题(请记住其他程序)。 / p>
答案 1 :(得分:0)
我终于找到了问题:启动的线程没有加入,pthread_create最终返回了一个错误代码,错误信息设置为“无法分配内存”。信号从未发送过,然后主线程被阻塞了。
我修复了此问题,为已启动的线程创建了新状态并在主循环中添加了连接。