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 ?
You should use volatile keyword to keep the variable updated among all threads. Using volatile is yet another way (like synchronized, atomic wrapper) of making class thread safe. Thread safe means that a method or class instance can be used by multiple threads at the same time without any problem.
You can protect data variables shared between threads using a threading. Lock mutex lock, and you can share data between threads explicitly using queue. Queue.
If you want synchronous communication between a main thread and a processing thread, you can use a SynchronousQueue. The idea is that the main thread passes data to the processing thread by calling put() , and the processing thread calls take() . Both are blocking operations.
Only one thread can read and write a shared variable at a time. When one thread is accessing a shared variable, other threads should wait until the first thread is done.
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));
}
}
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With