简体   繁体   English

如何使用QThreads使无锁的生产者使用者线程交换更安全

[英]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. 我对这个否则很好的例子的抱怨是: http : //blog.qt.digia.com/blog/2006/12/04/threading-without-the-headache/是它在交换裸露的指针并且没有使用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. 如果我在生产者中使用unique_ptr,当我调用产生的信号时将其释放,然后将裸指针直接放入连接的消耗插槽中的另一个唯一指针中,那会更安全。 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. 这仍然有几个主要问题:-当插槽未连接时,我不能防止泄漏-如果要连接多个插槽,则不能防止双重删除(如果编程的话,这对于程序员是一个逻辑错误发生了,但我想检测出来)-我不太了解Qt的内部工作原理,以确保在传输过程中没有泄漏。

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? 如果我要使用共享指针const,它将解决我所有的问题,但速度会变慢,据我所知,我必须按如下所述在元对象系统中注册它: http : //qt-project.org/ doc / qt-4.8 / qt.html#ConnectionType-enum这是个好主意吗?

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. 而是传递const引用,以允许插槽复制对象。 If you use Qt's container classes, this should not hinder performance, as Qt's container classes implement copy-on-write. 如果您使用Qt的容器类,这不会影响性能,因为Qt的容器类实现了写时复制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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