简体   繁体   English

使用 C++ std::vector 作为线程中的队列

[英]Using a C++ std::vector as a queue in a thread

I would like to have items added to a queue in one thread via in an asynchronous web request handler:我想通过异步 web 请求处理程序将项目添加到一个线程中的队列中:

void handleRequest(item) {
    toProcess.push_back(item);
}

There is a background thread that constantly processes these queue items as follows:有一个后台线程不断处理这些队列项,如下所示:

while(true) {
   for(auto item : toProcess) { doSomething(item); }
   toProcess.clear();
}

Clearly this isn't thread safe... you might add an item to toProcess right when the for loop finishes and thus have it cleared out without being processed.显然这不是线程安全的......您可以在 for 循环完成时将一个项目添加到 toProcess ,从而在不处理的情况下将其清除。 What would be the best model to program something like this?编写这样的程序的最佳 model 是什么?

I'm going to use std::atomic<T>::wait which is a C++20 feature, there is a way to do it with condition variables too however, and they exist since C++11 .我将使用std::atomic<T>::wait这是一个C++20特性,但是也有一种方法可以使用条件变量,并且它们自C++11以来就存在。

Include <atomic> and <mutex>包括<atomic><mutex>

You will need a member atomic_bool.您将需要一个成员 atomic_bool。
std::atomic_bool RequestPassed = false;
and a member mutex和一个成员互斥锁
std::mutex RequestHandleMutex;

Your handleRequest function would then become您的 handleRequest function 将变为

void handleRequest(item) {
    std::lock_guard<std::mutex> lg(RequestHandleMutex)
    toProcess.push_back(item);
    RequestPassed.store(true);
    RequestPassed.notify_all();
}

and your loop would be this你的循环就是这个

while(true) {
    RequestPassed.wait(false);
    std::lock_guard<std::mutex> lg(RequestHandleMutex)
    /* handle latest item passed */
    RequestPassed.store(false);
}

This way, the while thread waits instead of constantly iterating (saving cpu power and battery).这样,while 线程等待而不是不断迭代(节省 CPU 功率和电池)。 If you then use handleRequest , the atomic_bool gets notified to stop waiting, the request is handled (mutex is locked so no new requests can come while this happens), RequestPassed is reset to false, and the thread waits for the next request.如果您随后使用handleRequest ,则会通知 atomic_bool 停止等待,处理请求(互斥锁被锁定,因此在发生这种情况时不会出现新请求), RequestPassed 重置为 false,并且线程等待下一个请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM