PDA

View Full Version : qt multi threads



weixj2003ld
4th April 2009, 11:14
Hello,everry one.
I want do the following things with qt multi threads.But I do not know how to realize it?
main ()
{
.....
create thread1// do thing A
create thread 2// do thing B
do thing C.
......
}
I want to the thing C does after the A and B both have finished.When the program run,C did before A and B finish(because thread1 and thread2 have not finished), how Could I realize what I want to do?

wysota
4th April 2009, 11:25
What's the reason for using threads then? If you insist on using threads, use wait conditions or mutexes to synchronize them. Threads A and B will release respective mutexes and only then thread C will do its job. If you don't want to block thread C (if it's your GUI thread) then you have to use another approach. In that case read this article:
http://doc.trolltech.com/qq/qq27-responsive-guis.html

weixj2003ld
5th April 2009, 05:22
Thank you for your answer.

1.The reason for using thread.

main()
{
...
for(i=0;i<max;i++)
{
// there are a lot things will be done in this circle,and it will consume much time.
}
...
}
In order to decrease the time,I want to do it with multi -threads.

for(i=0;i<max/2;i++)
//threads A does
for(i=max/2+1;i<max;i++)
//threads B does.
2.When I create a class like this.

class A: public QThread
{
void run()
{
QMessageBox::warning(0,"dddd","ddddd",0,0,1);
}
}
run the progam,the following error will occur:
"Widgets must be created in the GUI thread.", file kernel/qwidget.cpp,
I know I do not inherit from gui widget,but if I write like this

class A: public QWidget,public QThread
{
void run()
{
QMessageBox::warning(0,"dddd","ddddd",0,0,1);
}
}
error still exists.
How could I do with it?

faldzip
5th April 2009, 07:57
You have to create Widgets in main (GUI) thread, so instead of


QMessageBox::warning(...);

use qDebug() to print to console or, for example, notify GUI thread via signal/slot about what you want to display as a QMessageBox and the GUI thread will do that in slot.

talk2amulya
5th April 2009, 09:43
are you sure u'd need 3 different threads to accomplish your tasks..using too many threads can be overkill and as explained in the article by wysota, will most of the times bring the performance of ur application down..try to use just one extra thread and see how ur app performs..to make sure u dont start task C before A and B..start an event loop in main()..let A and B be done in one thread..when they are done, emit a signal, which is caught in the main thread upon which the eventloop is quitted..then perform task C..


Class A&B : public QThread
{
protected run()
{
TaskA();
TaskB();
emit done();
}
signals:
done();
}

main thread:
int main(...)
{
//start thread A&B
QEventLoop loop;
connect(threadObject, SIGNAL(done()), &loop, SLOT(quit()));
loop.exec();
taskC();
....
}

if u read wysota's article carefully, u might have already figured that out by now.

wysota
5th April 2009, 10:00
In order to decrease the time,I want to do it with multi -threads.

for(i=0;i<max/2;i++)
//threads A does
for(i=max/2+1;i<max;i++)
//threads B does.
This is wrong. Either the for loops need to be inside the threads or you have to change your architecture. Otherwise you're losing computing power. I suggest you use QtConcurrent to manage multithreading for you - the runnables solution is something you want to have a look at.

weixj2003ld
5th April 2009, 17:03
Thanks for answer.
1. Now,I create 2 threads,the thread class like this:
mythread.h

class Mythread:public QThread
{
Mythread::Mythread(int start,int end,MyclassA *a)
void MyThread::run()
{

}
public:
MyclassA *a1;
int start1,end1;
}
mythread.cpp
Mythread::Mythread(int start,int end,MyclassA *a)
{
start1=start;
end1=end;
a1=a;
}
Mythread::run()
{
for(i=start1;i<end1;i++)
{
//do task.Myclass will be used here.
}
}
main.cpp
{
...
MyclassA myclassa is created.
.....
Mythread *thread1=new Mythread(0,10,myclassa);
Mythread *thread2=new Mythread(11,30,myclassa);
thread1.start();
thread2.start();
...
}
2.If I only create one thread(thread1,for example) and the program is ok,but if I create 2 threads,when I run the program,it will crash.Why?

talk2amulya
5th April 2009, 17:35
you shouldnt ignore what different replies you get in the posts..your case is a classic example for which Qt Concurrent is applicable..read about it and try to implement it..u wont have to use those multiple threads..Qt will take care of everything without letting anything crash..

weixj2003ld
6th April 2009, 03:45
Thank you for answering my question patiently.
My program built with qt4.3.1,and a lot of things have been done by other people,I am afraid I can not change it to upper version.but Q4.3.1 does not support Qt Concurrent.
I think I will manage the threads by myself ,but not Qt Concurrent.
My questions:
1.What should I do if I want to let Q4.3.1 support Qt Concurrent?
2. Can data type( class defined by user) be shared by threads?
Thank you.

wysota
6th April 2009, 07:39
Thank you for answering my question patiently.
My program built with qt4.3.1,and a lot of things have been done by other people,I am afraid I can not change it to upper version.but Q4.3.1 does not support Qt Concurrent.
Why can't you upgrade Qt?


2. Can data type( class defined by user) be shared by threads?
Not without proper synchronization. If you do synchronize using a mutex, then it can be shared. Some of the classes will be safe without synchronization but it depends on a case by case basis. And in general widgets can't be shared between threads, regardless if you do the synchronization or not.

weixj2003ld
7th April 2009, 12:04
A class(defined by myself) shared by the threads must be lock and unlock?

talk2amulya
7th April 2009, 12:10
yes, using mutex

weixj2003ld
7th April 2009, 12:15
when I used two threads like what I have said in my program and compile and run it,it will be crashed at radom position,Is it because of my not synchronizing my threads?Must I synchronize them?

talk2amulya
7th April 2009, 12:29
if there is a shared object, u have to make it thread-safe..and yes, synchronize..and again, why cant u upgrade Qt? u have a solution waiting for u in there, so i cant understand ur reluctance

weixj2003ld
7th April 2009, 14:52
Thanks for answer.
1.Why have not upgrate my Qt?
My colleagues and I all use qt4.3.1+ mysql+coin3d+msvc2005+carnac.If I upgrate my qt,they must.And a lot time will be wasted for built platform again.
2.If threads only read(not write) data from the shared class(created by myself),Must it be locked and unlocked?like this:
.....

class Mythread1
{
public:
Mythread1(SharedClass *sharedclass);
void calculate(SharedClass *sharedclass)
{
//read data from sharedclass and calculate
}
}


SharedClass *sharedClass=new SharedClass ();
init(A);
thread1=new Mythread1(A);
thread2=new Mythread1(A)
.....

Do I use mutex in SharedClass ?That is,must all the functions and varables in SharedClass be locked and unlocked?for example ,SharedClass like this:

class SharedClass
{
public:
A *a;
B *b;
QString str;
void function1();
}
How could I do?
Thank you.

talk2amulya
7th April 2009, 15:09
read about thread-safe classes.. thread-safe classes are those classes for which multiple threads can access the SAME instance of the class..u have to provide synchronization in these classes..i dunno what your application is doing..u have a number of possibilities to implement synchronisation depending upon what ur class does..

and you should consult with your fellow colleagues about the new Qt version...there r lots of other features that u will be missing and implementing yourself..which is MORE wasted time

weixj2003ld
7th April 2009, 16:03
class SharedClass will be shared by all threads,and it structure is like this:

class SharedClass
{
public:
A *a;
B *b;
QString str;
void function1()
{
a=new A();
b=new B();

}
}
If I will let it thread-safe,Do I do like this?

class SharedClass
{
public:
A *a;
B *b;
QString str;
void function1()
{
QMutexLocker locker(&mutex);
a=new A();
b=new B();

}
private:
mutable QMutex mutex;
}
class a and b must be thread-safe also?

weixj2003ld
8th April 2009, 05:20
no answer ??

wysota
8th April 2009, 09:01
no answer ??

We have no idea what you are asking for. At least I know I don't...

weixj2003ld
8th April 2009, 11:00
We have no idea what you are asking for. At least I know I don't...
Sorry.
I explain my question again.
As we know ,if a class is shared by muti-threads,it should be thread-safe.Now I define a class ,and it will be shared by 2 threads.If I want to let it thread-safe,I do as follow,Am I right or not?


class SharedClass
{
public:
A *a;
B *b;
QString str;
void function1()
{
a=new A();
b=new B();

}
}

If I will let it thread-safe,I add code like this:


class SharedClass
{
public:
A *a;
B *b;
QString str;
void function1()
{
QMutexLocker locker(&mutex);
a=new A();
b=new B();

}
private:
mutable QMutex mutex;
}
By the way,Must class a and b be thread-safe?

wysota
8th April 2009, 14:05
If you post a code snippet without appropriate tags one more time, you will get a temporary ban on the forum.

No, a and b don't have to be thread safe.