繁体   English   中英

c ++ 11线程池在Windows上工作-Linux上的块

[英]c++11 thread pool works on windows - blocks on linux

编辑
我通过在Shared结构中使用单个互斥锁变量而不是在Unique中使用多个互斥锁解决了我的问题。 如果有人理解为什么这样有效,而另一个人却不可靠(可靠),我会很乐意接受一个答案。
编辑

我用c ++ 11线程编写了一个简单的线程池。 在Windows上,它的行为符合预期,但在Linux上,它会阻塞。 我以为我编程错了,并且它恰好在Windows上运行。

这个想法是一次创建一个池并多次调用run(),这将在所有可用线程上运行一次程序,然后在不破坏线程的情况下返回。 然后,线程等待下一次运行,依此类推。

在Windows上,每次尝试都可以使用。 但是在linux上,只有一个线程开始执行程序,此后什么也没有发生,所以run()从不返回。

我只包含源代码的一个精简版本,因为我认为事情可能太小了。 如果有人有兴趣看看,我怀疑代码部分中间的loop()和wait_all()是最相关的部分。 如果变量类型在名称/上下文中不清楚,我还将声明作为参考。

Pool::Pool(uint32_t num_threads) : num_threads_(num_threads), uniques_(num_threads), threads_(num_threads) {
    shared_.end  = false;

    for (uint32_t i = 0; i < num_threads; ++i) {
        uniques_[i].wake = false;
        threads_[i] = std::thread(loop, std::ref(uniques_[i]), std::ref(shared_));
    }
}

void Pool::run(Program program) {
    shared_.program = program;
    wake_all();
    wait_all();
}

void Pool::wake_all() {
    for (size_t i = 0; i < uniques_.size(); ++i) {
        uniques_[i].wake = true;
    }

    shared_.wake_signal.notify_all();
}

void Pool::wait_all() {
    for (size_t i = 0; i < num_threads_; ++i) {
        std::unique_lock<std::mutex> locker(uniques_[i].lock);
        uniques_[i].done_signal.wait(locker, [&]{return !uniques_[i].wake;});
    }
}

void Pool::loop(Unique& unique, Shared& shared) {
    for (;;) {
        std::unique_lock<std::mutex> locker(unique.lock);
        shared.wake_signal.wait(locker, [&]{return unique.wake;});

        if (shared.end) {
            break;
        }

        // Do stuff... On linux only a single thread gets here
        shared.program();

        unique.wake = false;
        locker.unlock();
        unique.done_signal.notify_all();
    }
}

// Declaration
class Pool {
public:
    typedef std::function<void()> Program;
    Pool(uint32_t num_threads);
    void run(Program program);
private:
    void wake_all();
    void wait_all();

    struct Unique {
        std::condition_variable done_signal;
        std::mutex lock;
        bool wake;
    };

    struct Shared {
        Program program;
        std::condition_variable wake_signal;
        bool end;
    };

    uint32_t num_threads_;
    Shared shared_;
    std::vector<Unique> uniques_;
    std::vector<std::thread> threads_;

    static void loop(Unique& unique, Shared& shared);
};

您违反了呼叫wait的标准要求:

无效等待(unique_lock&lock);

要求:lock.owns_lock()为true,lock.mutex()由调用线程锁定,并且:

—没有其他线程在此condition_variable对象上等待,或者

— lock.mutex()对于所有同时等待(通过wait或timed_wait)线程提供的锁参数,返回相同的值。

您可以同时等待线程,这些线程的lock指向另一个mutex 因此,您不满足在condition_variable上调用wait的先决condition_variable

我相信您可以使用condition_variable_any ,它没有此要求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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