这种线程间通信的方法是否安全? [英] Is this method of inter-thread-communication safe?

查看:184
本文介绍了这种线程间通信的方法是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个对象(继承自 QObject ),每个对象包含一个单独的 std :: list 。每个对象都在主gui线程中创建(没有父对象),然后被推送到自己的线程(使用Qt的 QObject :: moveToThread())。

I have 3 objects(inherited from QObject) that each contain a separate std::list. Each object gets created in the main gui thread (with no parent) and then is pushed to it's own thread (using Qt's QObject::moveToThread()).

每个线程都连接到一个gui,消息在不同线程之间与数据发送。每个线程基本上处理它自己的列表。例如:

Each thread is hooked up to a gui and messages are sent between the different threads with data. Each thread is to essentially handle it's own list. For example:

Obj 1:数据的消费者。它的pop是它的列表的前面(如果数据存在)使用。它还有一个SLOT可用,以便其他线程可以推送数据到它。没有其他对象可以直接访问此列表,只有原始的QObject类。

Obj 1 : Consumer of data. It pop's the front off of its list(if data is present) to use. It also has a SLOT available so that other threads can push data to it. No other object can access this list directly only the the original QObject class.

Obj 2:数据的生成器。它将数据推送到其列表。它有SLOTS可供其他人ping它的数据,从而从其列表中发出一个SIGNAL弹出数据。没有其他对象可以直接访问此列表。

Obj 2 : Producer of data. It pushes data to its list. It has SLOTS available for others to 'ping' it for data which will in turn emit a SIGNAL popping data from its list. No other object can access this list directly.

Obj 3:生成obj 1的数据并使用obj 2的数据。它有自己的内部数据结构,发送到obj 1的数据和来自obj 2的数据。在做一些分析后,它最终会将两个数据集推送到一些 QwtPlots

Obj 3: Produces data for obj 1 and consumes data from obj 2. It has it's own internal data structures that keep track of the data sent to obj 1 and the data coming from obj 2. It finally will push both data sets to some QwtPlots after it does some analysis.

Obj的1和2是实时的初始化,并使用QueryPerformanceCounter风格的timing,这将基本上在每个CPU运行时吸收CPU。他们运行 QCoreApplication :: processEvents()每个循环来处理下来的事件。

Obj's 1 and 2 are real-time critial and use QueryPerformanceCounter style 'timing' which will essentially suck down a CPU each while they're running. They run QCoreApplication::processEvents() every loop to handle the events that come down through.

好的方式来处理跨线程数据共享?如果不是,孔在哪里,你将如何纠正他们?我知道这将创建很多副本的数据飞来飞去,但内存膨胀在这一点上不是一个问题。

Is this an okay way to handle cross-thread data sharing? If it isn't, where are the holes and how would you correct them? I understand this will create a lot of 'copies' of data flying around, but memory bloat isn't a concern at this point.

提前感谢:)


thanks in advance :)

推荐答案

很难说是否是线程安全的,没有所有的实现细节,因为有很多事情可以去使用线程时出错。

It's hard to say exactly whether it's thread-safe or not without all the implementation details as there are a lot of things that can go wrong when using threads.


Obj 1:数据消费者。它的pop是它的列表的前面(如果数据存在)使用。它还有一个SLOT可用,以便其他线程可以推送数据到它。没有其他对象可以直接访问此列表只有原始的QObject类。

Obj 1 : Consumer of data. It pop's the front off of its list(if data is present) to use. It also has a SLOT available so that other threads can push data to it. No other object can access this list directly only the the original QObject class.

如果此插槽连接到其他线程作为Obj 3)使用排队或自动连接类型,则Obj 1可能是安全的。如果该槽直接从其他线程调用,那么它显然不是线程安全的,除非你明确同步所有。

If this slot is connected to signals in other threads (such as Obj 3) using queued or auto connection type, then the Obj 1 is probably safe. If the slot is called directly from other threads, then it obviously isn't thread safe unless you explicitly synchronize everything.


Obj 2:Producer数据的。它将数据推送到其列表。它有SLOTS可供其他人ping它的数据,从而从其列表中发出一个SIGNAL弹出数据。没有其他对象可以直接访问此列表。

Obj 2 : Producer of data. It pushes data to its list. It has SLOTS available for others to 'ping' it for data which will in turn emit a SIGNAL popping data from its list. No other object can access this list directly.

您没有提及如何实现pinging或哪些线程调用这些插槽。如果其他线程直接调用它们,如果ping操作涉及访问内部std :: list,那么你就遇到了麻烦。如果这些插槽只通过排队或自动连接(例如对于Obj 3中的某些信号)来调用,那么就没问题了。如果这些插槽是线程安全的(例如,他们只是把一个ping消息到某种内部同步消息队列),那么也很好。后一种方式看起来像排队连接机制的自定义重新实现。

You don't mention how "pinging" is implemented or which threads call those slots. If other threads call them directly and if pinging involves accessing the internal std::list, then you're in trouble. If those slots are only called via queued or auto connections (to some signal in Obj 3, for example), then it's fine. If those slots are thread safe (for example, they only put a "ping" message into some sort of internal synchronized message queue), then it's fine too. The latter way looks like custom reimplementation of the queued connection mechanism, though.

总的来说,这整个事情看起来对我太危险,因为插槽可以从任何地方被错误调用。我会尽量避免这种事情,通过进行一些安全检查,如下:

Overall, this whole thing looks too dangerous to me as slots can be called from anywhere by mistake. I'd try to avoid this kind of thing by putting some safety checks there, like this:

void Obj2::ping() {
    if (QThread::currentThread() != this->thread()) {
        // not sure how efficient it is
        QMetaObject::invoke(this, "ping", Qt::QueuedConnection);
        return;
    }
    // thread unsafe code goes here
}

这篇关于这种线程间通信的方法是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆