简体   繁体   中英

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:

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. What would be the best model to program something like this?

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 .

Include <atomic> and <mutex>

You will need a member atomic_bool.
std::atomic_bool RequestPassed = false;
and a member mutex
std::mutex RequestHandleMutex;

Your handleRequest function would then become

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). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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