Trying to understand semaphore
-
I am trying to understand semaphore by doing a sample.
but i am facing problem.
i created two thread both perform the same operation which is addition of some data and after that the result i am passing it through a function to display it in the Qline edit . But my data is not being displayed.
My code:
void add_thread::run() { int b = 0; int c = 0; qDebug("ADD_"); for (int a = 0; a < 10;++a) { addSem.acquire(); c = a + b; disSem.release(); qDebug("ADD_DATA %d",c); sleep(1000); b = c; emit ADD_Data(c); } qDebug("ADD_DATA %d",c); }
Another thread Code:
void display_thread::run() { int b = 0; int c = 0; for (int a = 10; a < 20; ++a) { disSem.acquire(); c = a + b; addSem.release(); b = c; emit ADD_Data1(c); sleep(1000); } }
Whether any mistake i Have done kindly help me is understanding it
-
qDebug("ADD_DATA %d",c);
Above statement is working ? Can show us where are you connecting with ADD_Data(c) signal ?
-
@ManiRon This is not really a good example as there is no need to synchronize the threads at all. You're using local variables in each run(), so you will not have race conditions. You should find a better example where you can see what happens without synchronisation and then add synchronisation.
Also, you're emitting signals in a loop that means slots will be executed after the loop is finished.
Did you connect the signals to the slot? -
qDebug("ADD_DATA %d",c);
It didnt work sir
My MainWindow Code:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); mProducer = new add_thread(this); mConsumer = new display_thread(this); connect(mProducer, SIGNAL(ADD_Data(int)), this, SLOT(dis_Data(int))); connect(mConsumer, SIGNAL(ADD_Data1(int)), this, SLOT(dis_Data1(int))); } MainWindow::~MainWindow() { delete ui; } void MainWindow :: dis_Data(int data1) { //QString s = data1; qDebug("ADD_DATA %d",data1); ui->lineEdit->setText(QString::number(data1)); } void MainWindow :: dis_Data1(int data1) { //QString s = data1; qDebug("ADD_DATA %d",data1); ui->lineEdit_2->setText(QString::number(data1)); } void MainWindow::on_pushButton_clicked() { mProducer->start(); mConsumer->start(); }
-
Your semaphores are not same. You are acquiring one semaphore and releasing another. This is the reason your threads are locked. Do like the follows.
addSem.acquire(); c = a + b; addSem.release();
-
but i have two thread running the how i can make it to acquire ?
-
I tried the way u told sir, Still that problem is not solved
-
Can you show me where are you creating the semaphore object ?
-
@dheerendra said in Trying to understand semaphore:
semaphore
its created seperately in a file
extern QSemaphore addSem; extern QSemaphore disSem;
But globally defined in MainWindow.cpp
-
I felt you are complicating it. Just create the QSemaphore addSem(1). You are not initialising the semaphore count. As simple stuff create the QSemaphore addSem(1) in main.cpp. Pass addSem to both the thread class.
Please note as @jsulm said, all this is not required. Since you would like to understand, we are showing you how to doit.
Another point is that - You better read how semaphores work in general. This understanding is must.
-
@dheerendra ok Sir
-
I think you are confusing semaphores with mutexes. When you have 1 resource to protect there's no need to use a semaphore.
Can you tell us where do wou declare
a
,addSem
anddisSem
?@jsulm said in Trying to understand semaphore:
you're emitting signals in a loop that means slots will be executed after the loop is finished.
Not totally correct. If the connected slot is in a thread with an active event loop it will execute "immediately".
-
Actually my aim was to check how the thread runs when we use a semaphore thats why thought of having a sample which displays each value after performing the addition but it just displays the first data after that the for loop is not running
-
This indicates that one thread has acquired & did not release the semaphore. Show us the code with your loop for both the threads.
-
@dheerendra actually i got both the values from both the thread but the value was only the first value then the next value were not updated donno whether my for loop is running?
-
@dheerendra
My thread Code:void add_thread::run() { int b = 0; int c = 0; qDebug("ADD_"); for (int a = 30; a < 40;++a) { addSem.acquire(); c = a + b; qDebug("ADD_DATA %d",c); disSem.release(); sleep(1000); b = c; addSem.available(); emit ADD_Data(c); sleep(1000); } qDebug("ADD_DATA %d",c); } My Other thread code: void display_thread::run() { int b = 0; int c = 0; for (int a = 10; a < 20; ++a) { addSem.acquire(); c = a + b; addSem.release(); b = c; addSem.available(); emit ADD_Data1(c); sleep(1000); } }
-
@ManiRon said in Trying to understand semaphore:
disSem.release();
My guess is right. Still you are releasing someother semaphore. Replace above line with addSem.release. Both the threads should work with same semaphore.
addSem.aquire() // do something addSem.release()