在主线程和子线程之间共享变量

5

我有一个类MainWindow,它在一个线程中打开一个server函数,我需要在主线程和子线程之间共享一个bool变量,我尝试使用volatile变量,但它不起作用,这是代码:

//Constructor
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //Some initialisation
...

    // Constructs the new thread and runs it. Does not block execution.
    bool_Server = true;//Variable supposed to be shared
    m_t1 = std::thread(lancerServeur, bool_Server);

}

MainWindow::~MainWindow()
{
    delete ui;
    bool_Server = false; //Variable supposed to be shared
    m_t1.join();
}


void MainWindow::lancerServeur(bool boolServer){
    serveur s;
    while(boolServer){
        s.receiveDataUDP();//Read data in non blocking mode
    }
}

易失变量是共享的吗?

1
你正在通过值传递变量。它怎么可能被共享呢?使用std::thread(lancerServeur, std::ref(bool_Server)),并将bool_Server设置为std::atomic<bool>或使用互斥锁等方法解决该问题。 - Simple
@Simple,论坛上有人告诉我它可以工作^^' - Evans Belloeil
@简单的方法不起作用,你能否提供一个带有头文件和cpp文件的答案? - Evans Belloeil
@EvansBelloeil:“论坛上有人告诉我它有效^^” 显然,您接受了这个答案得太快了,并没有阅读所有的评论。这个答案的作者告诉您一些完全错误的事情。 - πάντα ῥεῖ
2个回答

10
你正在将bool_Server的一个副本传递给MainWindow::lancerServeur,因此它观察的变量与原始的bool_Server没有任何连接。将其设为volatile并不能帮助解决问题,而且volatile也不能使对象访问在多线程中是安全的。
你应该使用atomic<bool>作为标记,并将其作为MainWindow的数据成员。无需将其传递给lancerServeur。以下是一个简单的示例,运行一个线程5秒然后退出。
#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>

struct MainWindow
{
  std::atomic<bool> stop_{false};
  std::thread task_;

  void run()
  {
    while(!stop_) {
      std::cout << "Processing ...\n";
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    std::cout << "Stopping ...\n";
  }

  void launch_thread()
  {
    task_ = std::thread(&MainWindow::run, this);
  }

  ~MainWindow()
  {
    stop_ = true;
    task_.join();
  }
};

int main()
{
  {
    MainWindow w;
    w.launch_thread();
    std::this_thread::sleep_for(std::chrono::seconds(5));
  }
}

2
在.h文件中将bool_Server更改为std::atomic<bool> bool_Server,并将您的.cpp文件更改为:
//Constructor
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //Some initialisation
...

    // Constructs the new thread and runs it. Does not block execution.
    bool_Server = true;//Variable supposed to be shared
    m_t1 = std::thread(lancerServeur, std::ref(bool_Server));

}

MainWindow::~MainWindow()
{
    delete ui;
    bool_Server = false; //Variable supposed to be shared
    m_t1.join();
}


void MainWindow::lancerServeur(std::atomic<bool>& boolServer){
    serveur s;
    while(boolServer){
        s.receiveDataUDP();//Read data in non blocking mode
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接