问题描述:
项目上需要实现一个功能,利用UI界面点击实现Qt UdpSocket解除绑定和重新绑定的功能。由于Udp接收数据之后要执行复杂的计算逻辑,为了避免阻塞UI界面,需要在子线程执行UDP数据的接收和处理工作。然而,在UI界面所在的线程调用udpsocket->abort();
会出现下面问题:
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x1ccdc5a0. Receiver '' (of type 'QNativeSocketEngine') was created in thread 0x0x1e9f23e8", file kernel\qcoreapplication.cpp, line 576
问题分析:
经过查阅发现Qt的UdpSocket的abort方法是线程不安全的,我们在主线程使用UdpSocket的引用并调用abort方法是在UI线程当中执行的,由于UdpSocket是在继承QThread类的run函数当中构造的,二者属于不同的线程,导致问题的发生。
解决思路
由于UdpSocket的abort方法不是一个槽函数,无法通过信号槽的第五个参数来控制在哪个线程当中执行。继承QThread的类除了run函数内构造的东西,其他都属于主线程。为此,考虑修改或自定义一个类MyUdpSocket