简体   繁体   中英

how to make lock free producer consumer thread exchange more exception safe with QThreads

The gripe I have with this otherwise good example: http://blog.qt.digia.com/blog/2006/12/04/threading-without-the-headache/ is that it is exchanging naked pointers and it is not using Qt::QueuedConnection.

Edit: here is the code snippet the above link shows (in case the link goes down before this post)

// 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();

If I used a unique_ptr in the producer, releasing it when I call the produced signal and directly put the naked pointer into another unique pointer in the connected consume slot it would be somewhat safer. Especially after some maintenance programmer has a go at the code ;)

void calculate()
{
    std::unique_ptr<std::vector<int>> pi(new std::vector<int>());
    ...
    produced(pi.release());     
    //prodiced is a signal, the connected slot destroys the object
    //a slot must be connected or the objects are leaked
    //if multiple slots are connected the objects are double deleted

}

void consume(std::vector<int> *piIn)
{
    std::unique_ptr<std::vector<int>> pi(piIn);
    ...
}

this still has a few major problems: -I am not protecting against leaks when the slot is not connected -I am not protecting against double deletes if multiple slots were to be connected (should be a logic error on the part of the programmer if it happens, but I would like to detect it) -I don't know the inner working of Qt well enough to be sure that nothing leaks in transit.

If I were to use a shared pointer to const it would solve all my problems but be slower and as far as I know I would have to register it with the meta object system as described here: http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum is this a good idea?

Is there a better way of doing this that I'm not thinking of?

You shouldn't pass pointers in a signal while expecting a slot to destroy them, because the slot may not be available.

Pass a const reference instead, allowing the slot to copy the object. If you use Qt's container classes, this should not hinder performance, as Qt's container classes implement copy-on-write.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM