views:

140

answers:

1

I have a QMainWindow with three widgets inside that are promoted to a class containing a subclassed QThread. They each draw on a local QImage in their rexpective qthread which is sent with a signal once its drawn and then rendered by calling update (mandlebrot example) from the slot. Is this safe or dangerous? They do not share any data, at least none that I am generating and am wondering what data they could be sharing that is outside of my coding range ie that is generated by Qt automatically.

+2  A: 

From the documentation:

QPainter can be used to paint onto QImage, QPrinter, and QPicture paint devices. Painting onto QPixmaps and QWidgets is not supported. On Mac OS X the automatic progress dialog will not be displayed if you are printing from outside the GUI thread.

Any number of threads can paint at any given time, however only one thread at a time can paint on a given paint device. In other words, two threads can paint at the same time if each paints onto separate QImages, but the two threads cannot paint onto the same QImage at the same time.

Note that on X11 systems without FontConfig support, Qt cannot render text outside of the GUI thread. You can use the QFontDatabase::supportsThreadedFontRendering() function to detect whether or not font rendering can be used outside the GUI thread.

So as long as you're careful about the font issue on X11, don't use any Pixmaps or Cursors (which are implemented as Pixmaps), and don't try to paint onto the same image at the same time from multiple threads... it should work.

Note that in the Mandelbrot example, the QImage is passed by value over the signal (implicitly shared), meaning that if either thread attempts a write it will get its own copy.

Hostile Fork
ok, these are the guidelines I have followed, do you forsee any issues with GDB on this though? Is it safe to use QLists inside a qthread?
yan bellavance
Debugging multithreaded code is always trickier than single-threaded, but the fact that you're drawing isn't going to change that. Qt data structures like QList are *reentrant* but not *thread-safe*...you have to lock them with a QReadWriteLock or QMutex if it will be possible for more than one thread to get its hands on the same QList at the same time. See: http://doc.trolltech.com/4.6/threads-reentrancy.html
Hostile Fork
I have seen a seg fault occur in the following code : http://www.mediafire.com/?mwjlm3yltej the class doesnt get any of its data members accessed by anything outside the thread and I get a seg fault only when I put a breakpoint. I wanna think it's gdb's fault but that would be a rare.I never ever got a seg fault at run time. If I copy the source code of the class three times and use it for each object instance I dont get this seg fault. when I step by step the code, it doesnt follow through and starts over (but in a different thread) so I am thinking that gdb is confused about all of this.
yan bellavance
this is in the run function and it doesnt seem to happen if the code looks low level ie if I dont put objects like QLists and such. All I did was to take the mandlebrot example, promote 3 widget inside a QMainWindow to mandlebrot, remove the code that draws the QImage inside run() and replace it with a simple function call and it happens in that function call. If you can look at it that would be great if not I understand.
yan bellavance
Well, I'm not going to compile and debug your code! :) However, if the debugger is not being helpful in finding the smoking gun, here's what you can try: see if you still get the problem if your something() function is just a while() loop that counts up to some big number. If not, keep adding bits back in until you figure out which code segment causes it.
Hostile Fork