【问题标题】:problem pthread_mutex_lock wait forever if it is inside for loop问题 pthread_mutex_lock 如果它在 for 循环中,则永远等待
【发布时间】:2020-12-24 18:46:07
【问题描述】:

我有一个如下函数,它获取两个指针、一个队列和一个命令,并将命令放入队列中。因为队列是两个线程之间的共享资源,所以我使用互斥锁。

int addtoQueue(Command_t* cmd,MyQueue_t* myQ){
    MyQueue_t *mq = myQ;
    pthread_mutex_lock(&mq->mu_queue);
    if(isFull(mq))
        return -1;
    insert(mq, cmd);
    pthread_mutex_unlock(&mq->mu_queue);
    pthread_cond_signal(&mq->cond);
    return mq->itemCount;
}

我在谷歌测试中写了一个测试程序如下。

TEST(QueueTest, AddOneElementToQueue) {
    MyQueue_t myQ;
    Command_t cmd;
    myQ.rear=0;
    myQ.front=0;
    myQ.itemCount=0;
    cmd.id=1;
    EXPECT_EQ(1, addtoQueue(&cmd, &myQ));
}


TEST(QueueTest, AddTenElementsToQueue) {
    MyQueue_t myQ;
    Command_t cmd[10];
    myQ.rear=0;
    myQ.front=0;
    myQ.itemCount=0;
    for(int i=0;i<9;i++){
        cmd[i].id=i;
        addtoQueue(&cmd[i], &myQ);
    }

    EXPECT_EQ(10, addtoQueue(&cmd[9], &myQ));
}

结果很奇怪,第一次测试我将一个命令放入队列中成功,但第二次卡在了

pthread_mutex_lock(&mq->mu_queue)

line inside addtoQueue 函数。我发现如果我在 for 循环中调用这个函数,它就会卡住。有什么问题?

【问题讨论】:

  • 如果 isFull 返回 true,则 addtoQueue 不会解锁互斥锁。
  • @ScottHunter 即使对于第一个元素,它也永远不会到达 isFull 并且如您所见,我只是在本地创建队列
  • 请不要编辑您的原始代码来添加您得到的答案建议的代码。这使得这些答案变得毫无意义(例如,当您编辑代码块时,它使 dreamcrash 的 答案变得毫无意义,因为这看起来他提出了一个不需要做的更改) .执行此操作的正确方法是将更新后的代码追加到您的问题中,但保持原始代码不变。或者,如果问题得到解决,您可以发布自己的答案以及完整的工作代码。
  • @CraigEstey 是的,我认为这可能会分散对某些不是原因的事情的回答
  • 当线程卡在互斥体中时,使用广播很有用!

标签: c for-loop pthreads mutex


【解决方案1】:

其实我忘了初始化 mutex 和 cond

TEST(QueueTest, AddTenElementsToQueue) {
    MyQueue_t myQ;
    Command_t cmd[10];
    pthread_mutex_init(&myQ->mu_queue, NULL);<-----here
    pthread_cond_init(&myQ->cond, NULL);<-------here
    myQ.rear=0;
    myQ.front=0;
    myQ.itemCount=0;
    for(int i=0;i<9;i++){
        cmd[i].id=i;
        addtoQueue(&cmd[i], &myQ);
    }

    EXPECT_EQ(10, addtoQueue(&cmd[9], &myQ));
}

添加这两行解决了问题所有测试通过

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 2021-10-30
    • 2023-01-20
    • 2018-06-09
    相关资源
    最近更新 更多