首页 > 解决方案 > wait_until 超时导致只有一个线程终止,无法捕获所有线程超时

问题描述

我做了一个简单的线程安全Buffer实现,创建了 10 个线程来处理buffer队列以随机推送和弹出一些数字。我的实现应该让等待弹出的线程只等待 3 秒然后终止。发生这种情况时,我会打印一条超时消息。

问题是只打印了一条超时消息,然后主线程将加入所有线程并返回。为什么?

这是代码,main.cpp

#include <thread>
#include <vector>
#include <iostream>
#include <sstream>
#include "Buffer.h"

int main() {

    std::vector<std::thread> workers;
    Buffer<std::string> buffer(3);

    srandom(time(NULL));

    for (int i = 0; i < 10; i++) {
        workers.emplace_back([&buffer]{
            long num = random();
            if(num%2==0) {
                std::stringstream msg;
                msg << std::this_thread::get_id() << " pushing " << num << std::endl;
                std::cout << msg.str();
                buffer.push(std::to_string(num));
            } else {
                std::stringstream msg1;
                msg1 << std::this_thread::get_id() << " waiting to pop" << std::endl;
                std::cout << msg1.str();
                std::string popped_string = buffer.pop();
                std::stringstream msg2;
                msg2 << std::this_thread::get_id() << " popped " << popped_string << std::endl;
                std::cout << msg2.str();
            }
        });
    }

    for (auto &w: workers) {
        if (w.joinable()) w.join();
    }

    return 0;
}

缓冲区.h

#ifndef PDS_CPP_BUFFER_H
#define PDS_CPP_BUFFER_H

#include <queue>
#include <mutex>
#include <condition_variable>

template <class T>
class Buffer {
private:
    std::queue<T> queue;
    std::mutex mutex;
    std::condition_variable cv;
    std::chrono::seconds sec;
public:
    Buffer(int time) : sec(time), queue() {};

    void push(T object) {
        std::lock_guard lockGuard(mutex);
        this->queue.push(object);
        this->cv.notify_one();
    }

    T pop() {
        std::unique_lock uniqueLock(mutex);
//        this->cv.wait(uniqueLock, [this]{ return !this->queue.empty(); });
        if(this->cv.wait_for(uniqueLock, this->sec, [this]{ return !this->queue.empty(); })) {
        } else {
            std::stringstream msg;
            msg << std::this_thread::get_id() << " timeout" << std::endl;
            std::cout << msg.str();
        }

        T object = this->queue.front();
        this->queue.pop();
        uniqueLock.unlock();
        return object;
    }
};


#endif //PDS_CPP_BUFFER_H

标签: c++multithreadingtemplatesmutexcondition-variable

解决方案


推荐阅读