创建一个以存储线程并调用它们的类

Creating a class to store threads and calling them

本文关键字:调用 一个以 存储 线程 创建      更新时间:2023-10-16

这是我要做的事情的简化版本:

#include <iostream>
#include <vector>
#include <thread>
#include <atomic>
class client {
private:
    std::vector<std::thread> threads;
    std::atomic<bool> running;
    void main() {
        while(running) {
            std::cout << "main" << std::endl;
        }
    }
    void render() {
        while(running) {
            std::cout << "render" << std::endl;
        }
    }
public:
    client() {
        running = true;
        threads.push_back(std::thread(&client::main, this));
        threads.push_back(std::thread(&client::render, this));
    }
    ~client() {
        running = false;
        for(auto& th : threads) th.join();
    };
};
int main() {
    client c;
    std::string inputString;
    getline(std::cin, inputString);
    return 0;
}

(注意:自写了问题以来已更改代码)

我要做的是创建一个为主循环(类),渲染和其他几件事的线程的类。但是,我无法使这个简化的版本起作用。我尝试使用Mutex锁定并解锁线程,但似乎没有任何帮助。我不知道为什么它不起作用,但我怀疑这是在threads.push_back(std::thread(this->main, this));中使用this的结果。

代码的当前结构不必保留...唯一的要求是将其自己的成员函数之一用作线程(并且该线程存储在类中)。我不确定这是否需要两个课程,或者我在一个班级中尝试这样做的方法是正确的方法。我已经看到了许多创建对象的示例,然后调用创建线程的成员。我试图避免这种情况,而是在构造函数中创建线程。

这里的问题是您不等待线程结束。在main中,您创建c。然后,这产生了线程。下一件事是返回摧毁c的返回。当c被摧毁时,它会破坏其成员。现在,如果线程尚未连接或分离,则将其销毁时,将调用std::terminate,并且程序结束

您需要做的是在破坏者中,将running设置为false,然后在两个线程上调用join。这将停止每个线程中的循环,并允许c正确破坏。

这样做,但是提出了另一个问题。running不是原子变量,因此在读取线程时写入它是未定义的行为。我们可以通过更改运行到提供同步的std::atomic<bool>来验证。

我还必须更改线程结构。当您要使用成员函数时,语法应为

std::thread(&class_name::function_name, pointer_to_instance_of_class_name, function_parameters)

因此,在这种情况下,它将是

threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));
相关文章: