PDA

View Full Version : Help me about multithread!



vql
3rd February 2007, 05:17
I am programming with multithread. In my program, I create a thread, how to wait this thread is finish before execute continue. Please see my simple program:

#include <QApplication>
#include <QThread>

class MyThread : public QThread
{
public:
MyThread();
void run();
};

MyThread::MyThread() : QThread()
{
}

void MyThread::run()
{
qWarning("Thread running.");
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyThread *thread = new MyThread;
thread->start();
qWarning("Output this line after thread finished.");
return 1;
}

Please modify my program to it output:

Thread running.
Output this line after thread finished.


Thanks a lot.

jpn
3rd February 2007, 08:14
QThread::wait()

e8johan
3rd February 2007, 08:18
Use a mutex that is unlocked by the thread when it is done.

wysota
3rd February 2007, 09:12
Why use a thread in such a situation? If the main thread is idle, why not use it to do the other thread's job?

^NyAw^
3rd February 2007, 12:31
Hi,


Why use a thread in such a situation? If the main thread is idle, why not use it to do the other thread's job?


I supose that "vql" is learnig how to work with threads.



int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyThread *thread = new MyThread;
thread->start();
thread->wait(); //Here the main thread will stop until your thread exits the run method
qWarning("Output this line after thread finished.");
return 1;
}

vql
3rd February 2007, 15:43
Ah, I programming with multithread, this program is very big. So I give a simple program to ask everybody. Thank NyAw' help. It solve my simple program.

In the big program, I use multithread. So I modify with 2 threads as following:

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyThread *thread1 = new MyThread;
thread1->start();
thread1->wait();
MyThread *thread2 = new MyThread;
thread2->start();
thread2->wait();
qWarning("Output this line after threads finished.");
return 1;
}

In this program, threre are 3 threads: thread1, thread2, mainthread. When call thread1->wait(), only mainthread wait thread1 finish or both of thread2 and mainthread wait thread1 finish.

At here, I want both thread1 and thread2 run at the same time, and they mustn't wait together. And They finish before call qWarning("Output this line after threads finished.");

My problem is that in my big program, there are a lot threads, I start them and want them finish before I call any commands after that. Thanks. Please help me. Example: I create two threads to get value to memory. I run them but at this time, I don't know it finish or not. Because, I need they finish before I operate with values get from threads.

wysota
3rd February 2007, 16:07
wait() blocks the thread that called it, so if you want both threads to run simoultaneously, you have to call wait() only when you called start() on both threads:

MyThread t1, t2;
t1.start();
t2.start();
t1.wait();
t2.wait();

vql
3rd February 2007, 16:22
If I use your code:


MyThread t1, t2;
t1.start();
t2.start();
t1.wait();
t2.wait();


When t1.wait() called, thread t2 will wait t1 finish or it run simoultaneously with t1.

jpn
3rd February 2007, 16:33
Both threads will run simultaneously.

vql
3rd February 2007, 16:43
Thank you. My problem is solved. And I have another question. If I don't declare thread as class variable. When I create a new thread. Do I know how many threads running in my program. There are a lot threads, how to make mainthread in idle status?

jpn
3rd February 2007, 17:32
In Qt a single QThread object represents a single thread. So obviously you want to store the pointers to those threads somewhere. It's a question of design where to keep them.

Anyway, the main thread is "idle" and able to handle events and such as long as it's running an event loop and you are not for example waiting another thread (calling QTread::wait() blocks until one of the conditions is met. See QThread::wait() docs for explanation of those "conditions".

I'd like to refer back to the question by wysota:

Why use a thread in such a situation? If the main thread is idle, why not use it to do the other thread's job?

vql
4th February 2007, 03:25
You don't understand my problem. I'm programming 3D using Coin library. I use thread to draw faster. Example: I want to draw Truck, Vessel to display on a form.

If I don't use thread:


truck.draw();
vessel.draw();
form.show();

Form will display truck & vessel.

But If i use thread:


truckthread.start(); // call truckthread.run(){draw()};
vesselthread.start(); // call vesselthread.run(){draw()};
form.show();


suppose at the time form.show() called, truckthread finished but vesselthread not finish. Form will only display truck. I want both truck & vessel displayed. Please solve it for me.

Finally, when use multithread, we must call start() for all threads, after that we must call wait() for all threads so that they finished before we call any commands after? Please view my tree:



thread1.start();
thread2.start();
// ...
threadn.start();

thead1.wait();
thead1.wait();
// ...
theadn.wait();

// you code after threads finished. At here, all threads finished?

wysota
4th February 2007, 09:10
Why do you say it'll display faster if you use threads? Have you actually verified that? As far as I know Coin uses OpenGL to do its job, which would suggest that if you're drawing a single scene using a single GL context in two or more threads without any synchronisation, you'll be asking for trouble.

Do you have a multiprocessor machine? Because if not, threads will only slow down your application.

vql
4th February 2007, 11:01
Please answer this first:
when use multithread, we must call start() for all threads, after that we must call wait() for all threads so that they finished before we call any commands after? Please view my tree:


thread1.start();
thread2.start();
// ...
threadn.start();

thead1.wait();
thead1.wait();
// ...
theadn.wait();
// you code after threads finished. At here, all threads finished?

This's right?

As you say, in Coin, we should use thread or not? My machine is multiprocessor.
Please answer that question.
Because, my program is 3D, have a lot trucks to draw (>1000), so I use object Truck as a thread to draw.
As you know, in Coin, I declare a variable SoSeparator *_root;
with each Truck, I call _root->addChild(truck->draw()).
After that, I need all of truck finish drawing to _root contain all nodes from trucks.
And call _examinerviewer->setSceneGraph(_root);
But because of truck is a thread, If I initialize 1000 Trucks to draw; there are some trucks not finish before call setSceneGraph.
Can you make a suggestion for my program? Thanks alot.

wysota
4th February 2007, 11:34
when use multithread, we must call start() for all threads, after that we must call wait() for all threads so that they finished before we call any commands after?
This's right?
Depends what you want. But if you want to block the flow until all the threads have finished their work, then that's correct. But it's highly inappropriate if your application is a GUI application - in such situation you should use signals and slots instead.


As you say, in Coin, we should use thread or not?
"Should"? No... "Can"? Possibly... First of all you'd have to make sure Coin3D is fully reentrant.



Can you make a suggestion for my program?

Forget about threads in all situations regarding display (rendering as well). You can use them (if you feel like it) for computation intensive fragments. For example you can do all computation intensive tasks in one thread and handle the gui in the other. But there is no point in spawning 1000 threads just to make a simple task. Thread spawning takes time, so everything you might gain from having threads run simoultaneously, you're likely to lose during thread initialisation.

I suggest you do some experiments if possible gains are worth the effort.

vql
4th February 2007, 12:03
Forget about threads in all situations regarding display (rendering as well).

I don't understand clearly. Does it relative with my example:


truckthread.start(); // call truckthread.run(){draw()};
vesselthread.start(); // call vesselthread.run(){draw()};
form.show();

We can't use threads in this case, because I want truck & vessel drawn on form.

wysota
4th February 2007, 14:27
If you can't use threads then why do you use them? I suggested you to stop using threads and you ask how is it related to your problem because you can't use threads? :confused:

vql
4th February 2007, 15:18
Thank you very much, wysota.
Finally. I want to ask wysota a question about Coin3D.
I can using Coin + SoQt + MingW (not Visual Studio) on Windows? I tried but failed when compiling Coin with MingW. Thanks.

vql
8th February 2007, 14:13
Anyone can give me a example about thread (use with classes QThread, QMutex, QMutexLocker, or QWailCondition). It's very complex when in my program, must combine above classes. Because, examples in Qt Assistant is very simple.

Thanks.

wysota
8th February 2007, 15:01
What exactly is that you want to achieve?