Threading without the headache

A couple of weeks ago, I started trying to find out if a pure virtual function can be made impure without breaking binary compatibility. "Why?" you ask? Because I want to make QThread::run() call QThread::exec() by default. We all know that threading is difficult to do, mostly because of the need to lock data, synchronize threads (with a QWaitCondition or QSemaphore, for example). However, it doesn't have to be.

Consider the following code snippet:

    // create the producer and consumer and plug them together
    Producer producer;
    Consumer consumer;
    producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce()));
    consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *)));

// they both get their own thread QThread producerThread; producer.moveToThread(&producerThread); QThread consumerThread; consumer.moveToThread(&consumerThread);

// go! producerThread.start(); consumerThread.start();

Wouldn't life be wonderful if it were that easy? The good news is, it already is, if you do just a small amount of work: subclass QThread and reimplement run() to simply call exec(). The code snippet above comes from an example [1] where I've done this. The end result is a solution to the Producer/Consumer problem without the need for a lock, a condition variable, or a semaphore. Hell, I don't even have to write a thread. I can do everything in a nice object oriented way; the Producer code goes in one place, the Consumer code in another, and then I move these into the wonderful black boxed thread object that does what I expect.

So what's the point of all this? I hope to be able to answer my original question: can a pure virtual function be made impure without breaking binary compabitlity? If so, I hope to make QThread::run() call exec() in Qt 4.3.

  1. producerconsumer.tar.gz