我编写了一个简单的类,它将使用 unique_lock 和 condition_variable 同时执行最多 N 个阻塞任务(N 在初始化期间指定)。
我的代码可以编译并运行,但只能按顺序运行。我在这里做错了什么?
class Work_Queue {
mutex lock;
condition_variable cv;
int thrd_ctr, max_thrd;
queue<pair<int, int>> wq;
map<int, int> am;
public:
Work_Queue(int cap) {
max_thrd = cap;
thrd_ctr = 0;
}
void churn() {
if (!wq.empty()) {
unique_lock<mutex> ul(lock);
cv.wait(ul, [this]() { return (thrd_ctr < max_thrd); });
auto [ip, id] = wq.front();
wq.pop();
++thrd_ctr;
cout << "thrd # " << thrd_ctr << " started" << endl;
ip++;
sleep(1);
cout << "thrd # " << thrd_ctr << " ended" << endl;
am[id] = ip;
--thrd_ctr;
cv.notify_all();
}
}
void do_work(int ip, int id) {
wq.push({ ip, id });
thread thrdobj([&]() { churn(); });
thrdobj.detach();
}
int get_ans(int id) {
while (am.find(id) == am.end()) {
// do nothing
}
return am[id];
}
};
int main() {
cout << "Number of cores: " << thread::hardware_concurrency() << endl;
Work_Queue q(4);
for (int i = 0; i < 6; ++i) {
q.do_work(i, i + 5);
}
for (int i = 0; i < 6; ++i) {
cout << q.get_ans(i + 5) << endl;
}
return 0;
}
我得到的输出是
Number of cores: 8
thrd # 1 started
thrd # 1 ended
1
thrd # 1 started
thrd # 1 ended
2
thrd # 1 started
thrd # 1 ended
3..
是什么导致它仍然按顺序运行以及如何修复它?
我检查了核心数量是否限制为 1 以防止并发,但是
thread::hardware_concurrency()
显示了多个核心。
我预计
thrd # 1 started
中的数字会高达4。
我的代码...运行但只能按顺序运行
我得到的输出是...
我认为你在问为什么当你的代码打印它时
thrd_ctr
总是1
。我对吗?如果是这样,那么答案很简单。 Christian Stieber 在评论中说过,但我会更详细地说明。
您的
churn
函数包含以下几行:
{
unique_lock<mutex> ul(lock);
...
++thrd_ctr;
cout << "thrd # " << thrd_ctr << " started" << endl;
...
cout << "thrd # " << thrd_ctr << " ended" << endl;
...
--thrd_ctr;
...
}
当任何线程命中
lock
语句时,thrd_ctr++
将被锁定,并且它保持锁定状态,直到线程执行 thrd_ctr--
。 lock
确保没有两个线程可以同时位于同一代码块中,并且每当任何线程从该代码块退出时,thrd_ctr
的值将与线程进入时的值相同(即,它将为零。)
P.S.,正如其他评论者所指出的,这不是您的示例中唯一的错误。