【问题标题】:Share a variable between main and thread在主线程和线程之间共享一个变量
【发布时间】:2026-01-02 08:40:02
【问题描述】:

我有一个类 MainWindowthread 中打开一个 server 函数,我需要在我的主线程和我的线程之间共享一个 bool variable,我尝试使用 volatile variable 但它没有工作,这是代码:

//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
    }
}

volatile 变量是否共享?

【问题讨论】:

  • 您正在按值传递变量。怎么可能共享?使用std::thread(lancerServeur, std::ref(bool_Server)) 并将bool_Server 设为std::atomic<bool> 或使用互斥锁等。
  • @Simple 论坛上有人告诉我它有效 ^^'
  • @SimpleDoesn't work,你能用头文件和cpp文件回答吗?
  • @EvansBelloeil '论坛上有人告诉我它有效 ^^'' 显然你接受这个答案有点太快了,并没有阅读那里的所有 cmets .这个答案的作者告诉你一些完全错误的事情。

标签: c++ multithreading qt c++11 network-programming


【解决方案1】:

您将bool_Server 的副本传递给MainWindow::lancerServeur,因此它所观察的变量与原始bool_Server 没有任何关联。将其设为volatile 将无济于事,并且volatile 无论如何也不会使对对象的访问成为线程安全的。

您应该使用atomic<bool> 作为标志,并使其成为MainWindow 的数据成员。无需将其传递给lancerServeur。这是一个简单的例子,运行一个线程 5s 然后退出。

#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&lt;bool&gt; 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
        }
    }
    

    【讨论】: