Qt 线程安全类,可重入类,不可重入类

18 篇文章 0 订阅

1、线程安全类:

不同线程对同一个类的对象进行操作,例如在不同线程调用同一个对象的类成员函数,是安全的,互不妨碍的,则说明该类是线程安全的,Qt中线程安全的类有QMutex、QMutexLocker、QReadWriteLock、QReadLocker、QWriteLocker、QSemaphore、QThreadStorage<T>以及QWaitCondition;


2、可重入类:

可重入类只能保证可以在不同线程中操作不同的此类的对象是安全的,不能保证,不同线程操作同一个此类对象,是安全的;绝大多数Qt的非图形界面类都符合一个并不太严格的要求:它们都必须是可重入的,及类的不同实例可同时用于不同的线程中;很多Qt的非图形用户界面类,包括QImage、QString和一些容器类,都使用了隐式共享作为一项优化技术,虽然这样的优化通常会让类变成不可重入的,但是Qt使用原子汇编语言语言指令来实现线程安全引用计数,这可以让Qt的隐式共享类变成可重入的;


3、不可重入类:

只能在一个线程中(一般是主线程)实例化对象,不能再其他线程中实例化该类的对象,可能是由于不同对象共享同一块内存,导致的;所有的QWidget和他的子类都是不可重入的,所以qt中的界面类实例化对象只能在主线程中,也不要试图把界面类对象的所属线程更改到子线程中,更不要在子线程中直接操作界面类对象,要使用信号与槽技术或其他技术。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 C++ Qt 中,跨线程传递对象指针时,如果接收线程中修改了指针指向的数据,会影响发送线程中对应指针指向的数据。这是因为不同线程之间共享同一份内存空间,所以一个线程中对内存的修改会影响到其他线程中对同一份内存的访问。 为了避免这种情况,可以采用以下方法: 1.使用线程安全容器,如 QMutex、QReadWriteLock 等来保护共享数据。 2.对于只读数据,可以采用深拷贝的方式,将数据复制到接收线程中进行操作,这样不会影响到发送线程中的数据。 3.对于可读写的数据,可以采用复制-修改-合并的方式,在接收线程中对数据进行修改后,将修改后的数据合并到发送线程中的数据中。 下面是一个示例代码,演示如何使用 QReadWriteLock 对共享数据进行保护: ```cpp // MyClass.h class MyClass : public QObject { Q_OBJECT public: MyClass(QObject *parent = nullptr); signals: void sendData(MyClass *obj); public slots: void receiveData(MyClass *obj); private: QString m_data; QReadWriteLock m_lock; }; // MyClass.cpp MyClass::MyClass(QObject *parent) : QObject(parent) { connect(this, &MyClass::sendData, this, &MyClass::receiveData); } void MyClass::receiveData(MyClass *obj) { QWriteLocker locker(&m_lock); // 加写锁 m_data = obj->m_data; // 修改共享数据 } // 在另一个线程中使用 MyClass *obj = new MyClass(); obj->m_data = "Hello"; emit obj->sendData(obj); ``` 在上面的示例中,MyClass 中定义了一个共享数据 m_data 和一个 QReadWriteLock 对象 m_lock,用来保护共享数据。在 receiveData 槽函数中,先加写锁,然后修改共享数据,最后释放锁。在另一个线程中,修改共享数据后,通过信号发送 MyClass 对象的指针。由于 QReadWriteLock 的保护,即使发送线程和接收线程同时访问共享数据,也不会出现数据不一致的情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值