为什么线程池中的condition_variable没有被唤醒?

问题描述 投票:0回答:1

我自己写了一个线程池,Result类用于获取线程池任务的计算结果。最初,我使用简单的信号量机制来实现线程同步。代码如下:

void Semaphore::wait() {
    std::unique_lock<std::mutex> lock(mutex_);
    condition_.wait(lock, [&] { return count_ > 0; });
    --count_;
}

void Semaphore::signal() {
    std::unique_lock<std::mutex> lock(mutex_);
    ++count_;
    condition_.notify_all();
}

Any Result::get() {
    if (!isValid_)
        return "";
    sem_.wait();
    return std::move(any_);
}

void Result::setAny(Any any) {
    this->any_ = std::move(any);
    sem_.signal();
}

get()方法用于获取线程池中任务的计算结果。如果计算没有完成,get()将会被阻塞。线程池中调用setAny来存储任务的计算结果。

后来我想是否可以直接使用锁和condition_variables来实现同步,然后就放弃了Semaphore类,直接在get()和setAny()中使用锁和条件变量,但是发现线程会被阻塞当最后调用 get() 时。这是为什么?

顺便说一句,如果线程池中只有一个线程,程序可以顺利执行;但如果线程数大于1,并且任务数大于1,就会出现上述问题。代码如下:

Any Result::get() {
    if (!isValid_)
        return "";
    std::unique_lock<std::mutex> lock(mtx);
    cd.wait(lock);
    return std::move(any_);
}

void Result::setAny(Any any) {
    this->any_ = std::move(any);
    cd.notify_one();
}
c++ multithreading condition-variable
1个回答
0
投票

您所看到的很可能是虚假唤醒。等待条件变量可能会毫无理由地被虚假中断,您永远不应该在没有谓词的情况下等待条件变量。

© www.soinside.com 2019 - 2024. All rights reserved.