主线程上的条件变量块

时间:2019-03-03 10:49:29

标签: c multithreading race-condition

我想使用条件变量最多启动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);
}

出什么问题了?谢谢您的帮助:)

2 个答案:

答案 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最终返回了一个错误代码,错误信息设置为“无法分配内存”。信号从未发送过,然后主线程被阻塞了。

我修复了此问题,为已启动的线程创建了新状态并在主循环中添加了连接。