簡體   English   中英

主線程上的條件變量塊

[英]Condition variable blocks on main thread

我想使用條件變量最多啟動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中保存一個element->file->d_namestrdup並將該字符串保存在clientCtx中,而不是struct dirent * ,當然還要在運行時將其釋放

請注意,即使在main的末尾,也沒有closedir ,即使這不是真正的問題(請記住其他程序)。

我終於找到了問題:啟動的線程沒有加入,pthread_create最后返回了一個錯誤代碼,錯誤信息設置為“無法分配內存”。 信號從未發送過,然后主線程被阻塞了。

我修復了此問題,為已啟動的線程創建了新狀態,並在主循環中添加了連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM