【发布时间】:2021-07-26 12:34:12
【问题描述】:
我正在尝试实现 Single producer Multiple consumer ,但是下面的代码无法编译。 有人可以帮助解决这个错误吗?也可以从这个池中唤醒所有线程并且随机线程能够获取锁吗?
- TIA
` threadPool/main.cpp:4: /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:364:17:错误:没有匹配的构造函数用于初始化“_Gp”(又名 'tuple<:__1::__thread_struct void>') 新 _Gp(std::move(__tsp), ^ ~~~~~~~~~~~~~~~~~
ls/usr/bin/../include/c++/v1/type_traits:2422:12: error: call to implicitly-deleted copy constructor of 'typenamedecay::type'(又名'TestClass') return _VSTD::forward<_tp>(__t);
----------------------------------------------
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <condition_variable>
using namespace std;
class TestClass{
public:
void producer(int i) {
unique_lock<mutex> lockGuard(mtx);
Q.push(i);
lockGuard.unlock();
cond.notify_all();
}
void consumer() {
unique_lock<mutex> lockGuard(mtx);
cond.wait(lockGuard, [this]() {
return !Q.empty();
});
cout<<this_thread::get_id();
cout<<Q.front()<<endl;
Q.pop();
lockGuard.unlock();
};
private:
mutex mtx;
condition_variable cond;
queue<int> Q;
};
int main() {
std::cout << "Hello, World!" << std::endl;
int MAX_THREADS = std::thread::hardware_concurrency()-1;
vector<thread> ThreadVector;
TestClass testObj;
for(int i=0; i<MAX_THREADS; i++){
ThreadVector.emplace_back(&TestClass::consumer, std::move(testObj));
cout<<"Pool threadID:" <<ThreadVector[i].get_id()<<endl;
}
TestClass testObj2;
for(int i=0; i<10; i++) {
testObj.producer(i);
}
for(auto &&t : ThreadVector) {
t.join();
}
return 0;
}
`
Another version to call threads
int main()
{
std::vector<std::thread> vecOfThreads;
std::function<void(TestClass&)> func = [&](TestClass &obj) {
while(1) {
obj.consumer();
}
};
unsigned MAX_THREADS = std::thread::hardware_concurrency()-1;
TestClass obj;
for(int i=0; i<MAX_THREADS; i++) {
std::thread th1(func, std::ref(obj));
vecOfThreads.emplace_back(std::move(th1));
}
TestClass prod;
for(int i=0; i<10; i++) {
prod.producer(i);
}
for (std::thread & th : vecOfThreads)
{
if (th.joinable())
th.join();
}
return 0;
}
【问题讨论】:
-
mutex无法移动,因此TestClass无法移动(更不用说您在同一对象的循环中执行std::move,这是一种未指定的行为)。如果你想在线程之间共享TestClass然后在堆上分配它,例如改用std::shared_ptr(或其他东西),并传递该指针。您也可以将其传递为&testObj,但为此您需要特别注意活性。
标签: c++ multithreading producer-consumer condition-variable