C++11 线程不加入

标签 c++ multithreading c++11

我有使用 Java 线程的经验,但想学习如何在 C++11 中使用它们。我尝试制作一个简单的线程池,其中线程创建一次并可以被要求执行任务。

#include <thread>
#include <iostream>

#define NUM_THREADS 2

class Worker
{
public:
    Worker(): m_running(false), m_hasData(false)
    {

    };
    ~Worker() {};

    void execute()
    {
        m_running = true;

        while(m_running)
        {
            if(m_hasData)
            {
                m_system();
            }
            m_hasData = false;
        }
    };

    void stop()
    {
        m_running = false;
    };

    void setSystem(const std::function<void()>& system)
    {
        m_system = system;
        m_hasData = true;
    };

    bool isIdle() const
    {
        return !m_hasData;
    };
private:
    bool m_running;
    std::function<void()> m_system;
    bool m_hasData;
};

class ThreadPool
{
public:
    ThreadPool()
    {
        for(int i = 0; i < NUM_THREADS; ++i)
        {
            m_threads[i] = std::thread(&Worker::execute, &m_workers[i]);
        }
    };
    ~ThreadPool()
    {
        for(int i = 0; i < NUM_THREADS; ++i)
        {
            std::cout << "Stopping " << i << std::endl;
            m_workers[i].stop();
            m_threads[i].join();
        }
    };

    void execute(const std::function<void()>& system)
    {
        // Finds the first non-idle worker - not really great but just for testing
        for(int i = 0; i < NUM_THREADS; ++i)
        {
            if(m_workers[i].isIdle())
            {
                m_workers[i].setSystem(system);
                return;
            }
        }
    };
private:
    Worker m_workers[NUM_THREADS];
    std::thread m_threads[NUM_THREADS];
};

void print(void* in, void* out)
{
    char** in_c = (char**)in;
    printf("%s\n", *in_c);
}

int main(int argc, const char * argv[]) {
    ThreadPool pool;
    const char* test_c = "hello_world";
    pool.execute([&]() { print(&test_c, nullptr); });
}

这个的输出是:

hello_world
Stopping 0

之后,主线程暂停,因为它正在等待第一个线程加入(在 ThreadPool 的析构函数中)。由于某些原因,worker 的 m_running 变量未设置为 false,这使应用程序无限期地运行。

最佳答案

Worker::stop成员(member)m_running在主线程中写入,而在不同线程中执行时读取。这是未定义的行为。您需要保护来自不同线程的读/写访问。在这种情况下,我建议使用 std::atomic<bool>对于 m_running .

编辑:同样适用于 m_hasData .

关于C++11 线程不加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33195600/

相关文章:

C++ 链接器错误,对应从共享对象引用的项的 undefined reference

c - 如何将输入文件划分为 MapReduce 的碎片/文件

c++ - 将 lambdas 传递给 std::thread 并调用类方法

c++ - 当通过 const 引用传递的对象被添加到像 std::map 这样的容器时会发生什么?

今天的 C++ 多线程与 C++ 11 的流动情况 - 书籍建议

c++ - 来自普通函数的虚函数调用

c++ - GCC6 中 undefined reference 为 'rt' ,'pthread' ,'stdc++fs'

c++ - 显示最长的递增子序列

java - LRU缓存的最佳实现方式

Android 默认线程及其使用