QT定时器和 多线程 问题,谢谢

时间:2022-06-28 23:33:12
线程1:
emit sign1;
sleep(2);//2秒
emit sign1;

主线程 槽:
timer 和 timeout槽 connect。

void slot()
{
    timer->start(1);//1毫秒
    qDebug("current time is %d\n",QTime::currentTime().msec());
}


void timeout()
{
  ....
}

打印的结果是:
current time is 334
current time is 339 只差了5ms。
然而,虽然我timer->start(1)是1ms,但是由于操作系统只能精确到20ms,所以第一次start,还没来得及timeout信号,第二个emit信号就来了。所以我2次emit间隔了2秒,但是系统最终的打印却显示只间隔5ms,我向可能是QT4里面做了优化,只保证能发送出信号,但是不保证及时,是这样吧?
请问,有什么解决方法吗,谢谢了

9 个解决方案

#1


no, there's no such solution......
unless your operating system can guarantee the timing signals

#2


那应该如何修改才可以啊?如果想达到这样的效果


引用 1 楼 zhu_xz 的回复:
no, there's no such solution......
unless your operating system can guarantee the timing signals

#3


有个问题挺纠结的,connect auto模式下,同步 和 异步的问题

文档说是 同一个线程,就是同步,不是一个线程就是异步。

这个线程改如何理解呢?

线程的概念,如果从QThread继承,那么就是run内部的才算线程,run外部的 成员函数 都不算,那么是否可以说只有在run内部emit,才算 异步呢?

而我的连接:connect(this->pParseThread,                                     SIGNAL(queueSendForTest(void *, int)),     this->pWindowfield[fieldIndex], SLOT(setQueueForTestMode(void *, int)));
在主线程连接的,虽然pParseThread是一个继承QThread的类,但是我没有在run中emit,run里面只是一个while(){sleep}的死循环(我知道这样没用),那这是否应该是同步连接呢?

但实验结果却是 异步的,如果我强制改第五个参数为 同步,那么就会报错:QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread

难道是QT自己优化了?发现我是auto模式,应该是同步,但又发现,我在子线程里操作GUI了,又给我优化成了异步?是这样吗


#4


connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal

#5


但两次sign就算sleep 20秒,和 2秒的结果还是一样的啊


引用 4 楼 openxmpp 的回复:
connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal

#6


引用 4 楼 openxmpp 的回复:
connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的函数呢?

#7



我那个定时器是 用作屏幕滚动的,只能用定时器啊,用线程计时,效果更不好。

我发射信号的时候,也分同步、异步,比如往主线程发射信号,修改界面,就用异步操作,效果还挺好

引用 6 楼 blueness883 的回复:
引用 4 楼 openxmpp 的回复:

connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的……

#8


其他那些解决了,因为虽然是再线程里,但是run里面发射,是异步,析构里,是同步。
最后一个问题是:
在线程的run里,为何发异步emit后,我sleep了 10秒,槽都还没执行呢,sleep一结束,槽立马就执行了




引用 6 楼 blueness883 的回复:
引用 4 楼 openxmpp 的回复:

connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的……

#9


其他那些解决了,因为虽然是再线程里,但是run里面发射,是异步,析构里,是同步。
最后一个问题是:
在线程的run里,为何发异步emit后,我sleep了 10秒,槽都还没执行呢,sleep一结束,槽立马就执行了



引用 1 楼 zhu_xz 的回复:
no, there's no such solution......
unless your operating system can guarantee the timing signals

#1


no, there's no such solution......
unless your operating system can guarantee the timing signals

#2


那应该如何修改才可以啊?如果想达到这样的效果


引用 1 楼 zhu_xz 的回复:
no, there's no such solution......
unless your operating system can guarantee the timing signals

#3


有个问题挺纠结的,connect auto模式下,同步 和 异步的问题

文档说是 同一个线程,就是同步,不是一个线程就是异步。

这个线程改如何理解呢?

线程的概念,如果从QThread继承,那么就是run内部的才算线程,run外部的 成员函数 都不算,那么是否可以说只有在run内部emit,才算 异步呢?

而我的连接:connect(this->pParseThread,                                     SIGNAL(queueSendForTest(void *, int)),     this->pWindowfield[fieldIndex], SLOT(setQueueForTestMode(void *, int)));
在主线程连接的,虽然pParseThread是一个继承QThread的类,但是我没有在run中emit,run里面只是一个while(){sleep}的死循环(我知道这样没用),那这是否应该是同步连接呢?

但实验结果却是 异步的,如果我强制改第五个参数为 同步,那么就会报错:QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread

难道是QT自己优化了?发现我是auto模式,应该是同步,但又发现,我在子线程里操作GUI了,又给我优化成了异步?是这样吗


#4


connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal

#5


但两次sign就算sleep 20秒,和 2秒的结果还是一样的啊


引用 4 楼 openxmpp 的回复:
connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal

#6


引用 4 楼 openxmpp 的回复:
connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的函数呢?

#7



我那个定时器是 用作屏幕滚动的,只能用定时器啊,用线程计时,效果更不好。

我发射信号的时候,也分同步、异步,比如往主线程发射信号,修改界面,就用异步操作,效果还挺好

引用 6 楼 blueness883 的回复:
引用 4 楼 openxmpp 的回复:

connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的……

#8


其他那些解决了,因为虽然是再线程里,但是run里面发射,是异步,析构里,是同步。
最后一个问题是:
在线程的run里,为何发异步emit后,我sleep了 10秒,槽都还没执行呢,sleep一结束,槽立马就执行了




引用 6 楼 blueness883 的回复:
引用 4 楼 openxmpp 的回复:

connect不是有五个参数吗 最后一个可以指定连接方式
你要精确计算的话 就不建议使用signal


确实,需要计时的功能,不应该这样跨线程靠timer来设计。
很少在设计里面需要固定计时来做业务的,一般都是触发式的设计。

举例来讲A->B线程发信号,没法保证这个时候B正处于空闲监听状态,如果B这个时候正在run什么特定的费时的……

#9


其他那些解决了,因为虽然是再线程里,但是run里面发射,是异步,析构里,是同步。
最后一个问题是:
在线程的run里,为何发异步emit后,我sleep了 10秒,槽都还没执行呢,sleep一结束,槽立马就执行了



引用 1 楼 zhu_xz 的回复:
no, there's no such solution......
unless your operating system can guarantee the timing signals