C++中的线程队列

虚拟现实

目前正在处理一个项目,我目前正在努力处理线程和队列,问题是所有线程都在队列中使用相同的项目。

可复制的例子:

#include <iostream>
#include <queue>
#include <thread>

using namespace std;

void Test(queue<string> queue){
    
    while (!queue.empty()) {
    
        string proxy = queue.front();
        cout << proxy << "\n";
        
        queue.pop();
    
    }
    
}

int main()
{
    
    queue<string> queue;
    
    queue.push("101.132.186.39:9090");
    queue.push("95.85.24.83:8118");
    queue.push("185.211.193.162:8080");
    queue.push("87.106.37.89:8888");
    queue.push("159.203.61.169:8080");
    
    std::vector<std::thread> ThreadVector;
    
    
    for (int i = 0; i <= 10; i++){
        ThreadVector.emplace_back([&]() {Test(queue); });
    }
    
    for (auto& t : ThreadVector){
        t.join();
    }

    ThreadVector.clear();

    return 0;
}
鲁克斯

看看这个片段:

void Test(std::queue<std::string> queue) { /* ... */ }

在这里,您将队列对象副本传递给线程。

该副本对于每个线程都是本地的,因此在每个线程退出后它都会被销毁,因此最终您的程序对queue驻留在main()函数中的实际对象没有任何影响

要解决此问题,您需要使参数采用引用或指针:

void Test(std::queue<std::string>& queue) { /* ... */ }

这使得参数直接引用queue内部存在对象,main()而不是创建副本。

现在,上面的代码仍然不正确,因为queue它容易发生数据竞争std::queue也不std::cout是线程安全的,并且在当前被另一个线程访问时可能会被另一个线程中断。为了防止这种情况,请使用std::mutex

// ...
#include <mutex>

// ...

// The mutex protects the 'queue' object from being subjected to data-race amongst different threads
std::mutex mut;

void Test(std::queue<std::string>& queue) {
    std::queue<std::string> tmp;
    {
        // Swap the actual object with a local temporary object while being protected by the mutex
        std::lock_guard<std::mutex> lock(mut);
        std::swap(tmp, queue);
    }
    while (!tmp.empty()) {
        std::string proxy = tmp.front();
        {
            // Call to 'std::cout' needs to be synchronized
            std::lock_guard<std::mutex> lock(mut);
            std::cout << proxy << "\n";
        }
        tmp.pop();
    }
    {
        // Now swap back the temporary into the main object
        std::lock_guard<std::mutex> lock(mut);
        std::swap(queue, tmp);
    }
}

这会同步每个线程调用,并在线程queue仍在访问时阻止来自任何其他线程的访问。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章