如何使用QThreads使无锁生产者消费者线程交换更加异常安全

时间:2012-11-28 16:08:07

标签: c++ qt c++11 signals-slots move-semantics

我对这个非常好的例子感到抱怨:http://blog.qt.digia.com/blog/2006/12/04/threading-without-the-headache/是它正在交换裸指针并且它没有使用Qt :: QueuedConnection。

编辑:这是上面链接显示的代码段(如果链接在此帖子之前关闭)

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

如果我在生产者中使用了unique_ptr,当我调用生成的信号并将裸指针直接放入连接的消耗槽中的另一个唯一指针时释放它会更安全一些。特别是在一些维护程序员有一个代码之后;)

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);
    ...
}

这还有一些主要问题: - 当没有连接插槽时,我无法防止泄漏 - 如果要连接多个插槽,我不能防止双重删除(如果发生这种情况,应该是程序员的逻辑错误,但我想检测它) - 我不太了解Qt的内部工作,以确保在运输过程中没有任何泄漏。

如果我要使用一个指向const的共享指针,它会解决我的所有问题,但速度会慢一些,据我所知,我必须将元素系统注册到此处所述:http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum是这个一个好主意?

有没有更好的方法来做到这一点,我没想到?

1 个答案:

答案 0 :(得分:0)

您不应该在信号中传递指针,同时期望一个插槽来销毁它们,因为插槽可能无法使用。

改为传递const引用,允许插槽复制对象。如果你使用Qt的容器类,这不应该妨碍性能,因为Qt的容器类实现了copy-on-write。