c - 主线程上的条件变量块
问题描述
我想使用条件变量最多启动 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);
}
问题是什么?感谢您的帮助 :)
解决方案
警告您在单独的线程中使用readdir的值,而对多线程没有任何保护,因此当您(尝试)printf client->file->d_name
时,您可能正在同时在主线程中执行readdir修改保存的结果,这有一个未定义行为。
例如,您需要在main中保存strdup并将该字符串保存在clientCtx而不是 中,当然还要在运行中释放它element->file->d_name
struct dirent *
还要注意main末尾缺少一个closedir ,即使在这种情况下这不是一个真正的问题(只需记住您的其他程序)。
推荐阅读
- javascript - 如何使用 postcss 在 css 中附加属性?
- r - r中绘图中的文本和非连续线
- node.js - Sequelize - 使用字符串数组作为输入查询字符串字段
- django - 如何在不将 DJANGO_SETTINGS_MODULE 设置为环境变量的情况下创建 django 包?
- database - 如何连接统一数据库
- flutter - FutureBuilder Firestore 分页
- c++ - libavcodec:如何将原始视频(YUV420P)帧编码为有效位图以保存到“.bmp”文件?
- python - Azure 容器实例上的 Python ML 部署失败
- java - 为什么我不能通过直接访问来获取单例实例?
- android - 卡在谷歌播放控制台中的目标受众和内容