多线程代码仅按顺序运行

问题描述 投票:0回答:1

我编写了一个简单的类,它将使用 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。

c++ concurrency condition-variable unique-lock
1个回答
0
投票

我的代码...运行但只能按顺序运行

我得到的输出是...

认为你在问为什么当你的代码打印它时

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.,正如其他评论者所指出的,这不是您的示例中唯一的错误。

© www.soinside.com 2019 - 2024. All rights reserved.