Reputation: 2503
I got a class MainWindow
that open a server
function in a thread
, I need to share a bool variable
between my main and my thread, I try to use volatile variable
but it doesn't work, here's the code :
//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
}
}
Is the volatile variable shared ?
Upvotes: 5
Views: 10487
Reputation: 109089
You're passing a copy of bool_Server
to MainWindow::lancerServeur
, so the variable it's observing is not in any way connected to the original bool_Server
. Making it volatile
isn't going to help, and volatile
doesn't make access to an object thread-safe anyway.
You should use an atomic<bool>
as the flag, and make it a data member of MainWindow
. There's no need to pass it to lancerServeur
. Here's a simple example that runs a thread for 5s and then quits.
#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));
}
}
Upvotes: 11
Reputation: 14390
In the .h file change bool_Server
to be std::atomic<bool> bool_Server
and change your .cpp file to be:
//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
}
}
Upvotes: 2