我在C ++中有以下代码,我试图从类的构造函数中产生新线程。我收到运行时错误。我不明白为什么,以及如何预防。我是C ++的新手。在VS2017中,已调用abort()中的错误。
#include <iostream>
#include <thread>
#include <chrono>
class Rectangle {
public:
int area(void);
Rectangle();
~Rectangle();
private:
int x, y;
int UpdateData();
};
Rectangle::Rectangle() {
x = 1;
y = 2;
std::thread modelThread(&Rectangle::UpdateData, this);
}
Rectangle::~Rectangle() {
}
int Rectangle::area() {
return x * y;
}
int Rectangle::UpdateData()
{
while (true) {
x++;
y += 2;
std::cout << "Area with x:" << x << " y:" << y << " area:" << Rectangle::area() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
return 0;
}
int main() {
Rectangle rect;
return 0;
}
答案 0 :(得分:2)
main
和modelThread
是线程,但是modelThread
是通过main
的构造函数从Rectangle
启动的。但是,当main结束时,rect
超出范围并被破坏,而在其构造函数中启动的线程仍在运行。这会导致运行时错误。
因此,您必须将modelThread
加入main
线程中,以确保主线程一直等到modelThread
完成运行。
但是现在,我无法在main函数中执行代码。我怎样才能做到
为此,您必须制作UpdateData
public
并像这样在main中启动modelThread
:
std::thread modelThread(&Rectangle::UpdateData, &rect);
即使使用std::async
,您也必须制作UpdateData
public
并像这样使用它:
std::future<int> fut = std::async (&Rectangle::UpdateData, &rect);
如果您不想制作UpdateData
public
,请在Rectangle类中声明一个friend
函数(可以访问其所有私有成员和函数)并在UpdateData
函数中调用friend
,并使用该main
函数在friend
中启动线程。
std::future<int> fut = std::async (&FriendFunc, &rect);
然后,您将可以在main
中执行代码,而无需等待UpdateData
完成。然后,您可以使用UpdateData
中的以下内容来获取由main
函数计算出的值。
int ret = fut.get();
如果您不想混用main
和UpdateData
的输出,请执行此操作。
在private
Rectangle
成员变量
std::mutex mtx; //uses <mutex>
并像这样使用它:
int Rectangle::UpdateData()
{
std::lock_guard<std::mutex> lock(mtx);
while (true) {
x++;
y += 2;
std::cout << "Area with x:" << x << " y:" << y << " area:" << Rectangle::area() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
return 0;
}