PDA

View Full Version : Two threads need to print on main window



zychu02
25th June 2014, 14:15
Hi all,

Can u help me with my task ? i need to make GUI app, which will cout on window:

Thread1
Thread2
Thread1
Thread2

i made a window which print Thread1 all the time, i made new object, with printing thread2, made a connection, but it doesn't work. I'll be glad if some1 will help me. in attach u can find some cpp files.i think i can't to that (dialog.cpp line 12,13)

anda_skoa
25th June 2014, 14:58
"It doesn't work" is not a very useful problem description.

What does happen and what do you expect to happen?

Cheers,
_

zychu02
25th June 2014, 18:21
Finally i made some progress. Sorry for my lack of information. Right know i have two threads, and i need them to print something like that:
Thread1
Thread2
Thread1
Thread2

Im making this as GUI App. Right now i don't know how to make global QMutex to lock them, :( cause right now it's like:

Thread1
Thread1
Thread1
Thread2
Thread2
Thread1
…..

Lesiok
25th June 2014, 20:44
Class MyThread and MyThread2 should be derived from one class which will have a defined static QMutex

anda_skoa
26th June 2014, 08:34
One thing that would work is to have two semaphores.
The first thread acquires the semaphore1 and releases semaphore2, the second thread does the opposite. The string sending happens in between the two semaphore operations in both threads.
After start, the main thread releases semaphore1, thus allowing the first thread to start with the ping-pong.

Cheers,
_

zychu02
29th June 2014, 18:27
I'm trying to resolve this problem with QSemaphore. I made two global semaphores ( first, second), and my thread methods look like):


void MyThread::thread()
{
for (int i = 0 ; i < 100; i++)
{
// stop here and wait for first available
if (first.available())
{
first.acquire(1); // first is now 0, so it's not available (blocked)
numberChange(QString("Thread 1"));
second.release(1); // release second semaphore, so he can start
}
}
void MyThread::thread2()
{
for ( int i = 0; i < 100; i++)
{
if (second.available())
{
second.acquire(1); // after acquire this semaphore should be block untill first thread is done
numberChange(QString("Thread 2"));
first.release(1); // release first semaphore so void MyThread::thread() can lock his semaphore
}
}
}

Is my thinking correct ? What I'm missing ?
My main problem is' how to make them stop and wait. Right now it's looks like they don't communicate correctly.

Thanks you

anda_skoa
29th June 2014, 18:35
That looks about right, though the available() checks do not make them stop as the comment suggested. Just remove them

How did you create them and how did you pass them to the two thread objects?

Cheers,
_

zychu02
29th June 2014, 18:49
Hi Anda,

When i removed available() i get deadlock after first cout "Thread 1".


I made a new class with .h and .cpp

h.
#ifndef SEMA_H
#define SEMA_H
#include <QSemaphore>

extern QSemaphore first;
extern QSemaphore second;


#endif // SEMA_H

.cpp
#include "sema.h"

QSemaphore first(1); // is this a binary semaphore ?
QSemaphore second(0); // 0 cause in void MyThread::thread() i have "second.release(1)". 0 should prevent after first loop to acquire "second.available(2)";

I have found that, if first or second is not available, the loop is still going, and i think i need to stop it and wait for another semaphore.

Maybe here is the problem. I found this global semaphore "solution" on web.
But this don't work as i want, so i'm doing something wrong.

Thank you Anda for quick reply

anda_skoa
29th June 2014, 21:43
Global variables are not very nice but should work nevertheless.

Can you attach a minimum buildable example that shows the problem?

Cheers,
_

zychu02
30th June 2014, 07:11
First .h files

Second part .cpp files

anda_skoa
30th June 2014, 07:43
You are not starting the threads, you run two mehods in the main thread, one after the other.

To start a thread call its start() method.
This requests a platform thread and lets it execute the run() method.

Cheers,
_

zychu02
30th June 2014, 08:06
in mythread.h i can change first void thread() to void run(), and in cpp too. But what with the second ? I cannot have two run() methods. How to solve this . I think i'll need to buy some fine quality beers for your help Anda.

Thank you,

anda_skoa
30th June 2014, 08:20
There are a couple of option:

- Two thread classes
- Switching behavior depending on an argument passed to the thread class constructor
- A templated thread class that delegates to a method of an instance of the template argument
- Two implementations of QRunnable and a dedicated threadpool with two threads.
- Something similar but with two dedicated threads.

The second one is probably the easiest given your current code.
The run() method evaluates the stored argument value and then calls either thread() or thread2()

Cheers,
_

zychu02
30th June 2014, 08:42
Anda..... it's working ! Thank you so much, for your time and patience. Send me private msg with your address so i can send you "Żubrówka" bottle. :)

Thank you again, have a nice day,