【问题标题】:how to make lock free producer consumer thread exchange more exception safe with QThreads如何使用 QThreads 使无锁生产者消费者线程交换更安全的异常
【发布时间】:2012-11-28 16:08:07
【问题描述】:

我对这个很好的例子的抱怨:https://www.qt.io/blog/2006/12/04/threading-without-the-headache 是它正在交换裸指针并且它没有使用 Qt::QueuedConnection。

编辑:这是上面链接显示的代码 sn-p(以防链接在这篇文章之前失效)

// 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 这是一个好的想法?

有没有我没想到的更好的方法?

【问题讨论】:

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


    【解决方案1】:

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

    改为传递一个 const 引用,允许插槽复制对象。如果你使用 Qt 的容器类,这应该不会影响性能,因为 Qt 的容器类实现了写时复制。

    【讨论】:

    • 对不起,我忽略了这个例子没有使用 Qt::QueuedConnection 也改变了整个情况。
    • 然后简单的传值,使用Qt的容器类,比如QList、QVector等,因为它们无论如何都实现了COW,或者使用共享指针,比如QSharedPointer。您问是否有更好的方法 - AFAIK 没有。
    • 好吧,我现在用 QSharedPointer 来实现它(我第一次发现 QSharedPointer 有很好的用途)。
    猜你喜欢
    • 2018-05-22
    • 2013-11-10
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多