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

C++ 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全,c++,qt,c++11,signals-slots,move-semantics,C++,Qt,C++11,Signals Slots,Move Semantics,我对这个好例子的抱怨是:它正在交换裸指针,而不是使用Qt::QueuedConnection 编辑:这是上面链接显示的代码片段(以防链接在本文之前关闭) 如果我在producer中使用一个惟一的ptr,在调用生成的信号时释放它,并直接将裸指针放入连接的消费槽中的另一个惟一指针中,那么会更安全一些。尤其是在一些维护程序员尝试代码之后;) void计算() { std::unique_ptr pi(新std::vector()); ... 产生(pi.release()); //Prodicted是

我对这个好例子的抱怨是:它正在交换裸指针,而不是使用Qt::QueuedConnection

编辑:这是上面链接显示的代码片段(以防链接在本文之前关闭)

如果我在producer中使用一个惟一的ptr,在调用生成的信号时释放它,并直接将裸指针放入连接的消费槽中的另一个惟一指针中,那么会更安全一些。尤其是在一些维护程序员尝试代码之后;)

void计算()
{
std::unique_ptr pi(新std::vector());
...
产生(pi.release());
//Prodicted是一个信号,连接的插槽会破坏对象
//必须连接插槽,否则对象会泄漏
//如果连接了多个插槽,则会双重删除对象
}
无效消耗(标准::向量*piIn)
{
标准::唯一的ptr pi(piIn);
...
}
这仍然有几个主要问题: -插槽未连接时,我无法防止泄漏 -如果要连接多个插槽,我不会防止双重删除(如果发生这种情况,程序员会有逻辑错误,但我想检测它) -我不太了解Qt的内部工作情况,因此无法确保在传输过程中没有泄漏

如果我使用一个指向const的共享指针,它将解决我所有的问题,但速度会慢一些,据我所知,我必须将它注册到元对象系统中,如下所述:这是个好主意吗


有没有一种我没有想到的更好的方法呢?

你不应该在一个信号中传递指针,而期望一个插槽破坏它们,因为这个插槽可能不可用


而是传递一个常量引用,允许插槽复制对象。如果您使用Qt的容器类,这不会影响性能,因为Qt的容器类实现了写时复制。

很抱歉,我忽略了一个事实,即示例也没有使用Qt::QueuedConnection,这改变了整个情况。然后只需传递值并使用Qt的容器类,如QList、QVector等。,因为它们实现了COW,或者使用共享指针,比如QSharedPointer。你问我是否有更好的方法——如果没有的话。好吧,我现在用QSharedPointer实现它(我第一次发现QSharedPointer的好用法)。
// 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();
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);
    ...
}