简体   繁体   English

C ++ 11线程未加入

[英]C++11 Threads Not Joining

I have experience with threads in Java but want to learn how to use them in C++11. 我有Java线程的经验,但想学习如何在C ++ 11中使用它们。 I tried to make a simple threadpool, where threads are created once and can be asked to execute tasks. 我试图创建一个简单的线程池,在该线程池中创建一次线程,然后可以要求它执行任务。

#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); });
}

The output of this is: 输出为:

hello_world
Stopping 0

After that, the main thread halts, because it's waiting for the first thread to join (in the destructor of the ThreadPool). 之后,主线程停止,因为它正在等待第一个线程加入(在ThreadPool的析构函数中)。 For some reason, the m_running variable of the workers is not set to false, which keeps the application running indefinitely. 由于某些原因,工作程序的m_running变量未设置为false,这会使应用程序无限期地运行。

In Worker::stop the member m_running is written in the main thread, while it is read in execute in a different thread. Worker::stop ,成员m_running是写在主线程中的,而成员m_running是在其他线程中执行的。 This is undefined behavior. 这是未定义的行为。 You need to protect read/write access from different threads. 您需要保护来自不同线程的读/写访问。 In this case I would recommend using std::atomic<bool> for m_running . 在这种情况下,我建议对m_running使用std::atomic<bool>

Edit: the same holds for m_hasData . 编辑: m_hasData的内容相同。

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

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