c++ - 跨线程函数调用修改变量

标签 c++ multithreading

我在尝试创建一个多线程程序时遇到了一些困难。它是一个非常简单的应用程序,我只是为了了解多线程的工作原理而创建的 :)

好的,事情是我有 2 个线程和 1 个变量,线程 1 应该每秒打印一次它们共有的变量(时间并不重要,这只是一个例子)然后线程 1 休眠 1第二个 Thread2 进来并将它的值编辑为完全不同的东西,下一次 Thread1 运行它应该打印 thread2 分配的新值,尽管这没有发生:/发生的事情是 Thread1 打印默认构造函数值,即使它得到改变了,它有点难以用语言解释,所以我链接了下面的简单示例,我希望有人能帮助我理解这一点。顺便说一句,我知道我应该使用互斥体或关键部分,因为我在两者之间共享资源,但由于它们从不同时运行,而且这只是一个简单的例子,我就把它省略了。

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
    Printer printer;

    std::thread thread1(&Printer::SetMessage, printer, printer); //Sets the new value of "New Message"
    std::thread thread2(&Printer::Print, printer, &printer); //Prints the message using printf()

    while(true) {
        Sleep(5000); //i have a beakpoint here just to look at the variables once every 5 sec.
    }

    return 0;
}

打印机.cpp

void Printer::Print(Printer &obj) {
    while(true) {
        printf(obj.Message.c_str());
        Sleep(1000);
    }
}

void Printer::SetMessage(Printer &obj) {
    while(true) {
        Sleep(10000);
        obj.Message = "New Message";
    }
}

Printer::Printer(void){
    this->Message = "YOLO";
}


Printer::~Printer(void){}

所以我只是希望 Message 的值在所有其他线程中得到更新,我的意思是它们使用相同的对象并更改同一个该死的对象中的值,但为什么它不会在线程之间保持更改???我很困惑:我只看到在同一个类中执行此操作的示例,一旦我使用多个类,它就会变得更加复杂(在我的大脑中)。

最佳答案

你通过了printer到线程构造函数,它复制对象,所以每个线程都有不同的Printer , 不是同一个对象。

事实上,您的代码甚至不应该编译,但是 std::thread在 Visual Studio 中有一个允许这种情况发生的错误(并且忽略了您编写的 &printer 将传递指针的事实,而 Printer::print(Printer& obj) 不接受指针)。

要传递对线程函数的引用,您需要使用 std::ref 包装对象这会创建一个 reference_wrapper<Printer>将参数作为对新线程的引用转发,而不是制作拷贝并将拷贝传递给新线程:

std::thread thread2(&Printer::Print, std::ref(printer), std::ref(printer));

但是,即使您修复了该问题,您的代码仍具有未定义的行为,因为两个线程在不使用互斥锁或原子操作安全地进行更新的情况下读取/写入同一内​​存位置是不安全且无效的。

关于c++ - 跨线程函数调用修改变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27410079/

相关文章:

不同类型的 C++ 模板错误

c++ - 无法在 QWebEngineView 中登录 google : This app may not be secure

c++ - Atom 和 i3/5 之间常见的 gcc C/C++ 标志?

c++ - 无法编译在不同类上调用静态函数的代码

java - 使用 2 个线程的更快输出

python - 所有线程均未与QThread以及QtSerialPort(对于Arduino)和Matplotlib一起运行

java - SwingUtilities.invokeLater(new Runnable()) 到底如何工作?

c - 串行代码比在 C 中只使用一个线程慢得多?

java - 多线程中的同步块(synchronized block)

C++仿函数编译错误