mysql5资源共享

 找回密码
 立即注册
查看: 1084|回复: 15

[QT] QT串口阻塞方式使用,关闭时怎么使其退出waitForReadyRead(-1)

[复制链接]

18

主题

470

帖子

990

积分

高级会员

Rank: 4

积分
990
发表于 2019-6-24 10:09:51 | 显示全部楼层 |阅读模式
在编程中,我对QT串口采用了阻塞的方式,开了一个子线程专门读取串口的数据,这样的话,有数据就读没有数据就睡眠的方式。
但是,却发现在关闭串口后,串口仍然在等待数据,子线程仍然睡在waitForReadyRead(-1)这里。
怎么样做,才能在需要关闭串口的时候,让waitForReadyRead(-1)退出?

回复

使用道具 举报

1

主题

20

帖子

49

积分

新手上路

Rank: 1

积分
49
发表于 2019-6-24 13:04:17 | 显示全部楼层
1、改成异步read
2、可以试试socket强制断开。比如soket.abort()
回复

使用道具 举报

4

主题

507

帖子

1082

积分

金牌会员

Rank: 6Rank: 6

积分
1082
发表于 2019-6-24 14:02:18 | 显示全部楼层
没有办法的,除非你开另外一个串口,给它发东西
你看下源码就知道了。
while(msecs==-1||qt_subtract_from_timeout(msecs,stopWatch.elapsed())>0);


换成异步吧,或者不要waitForReadyRead(-1),你改成这样不好吗


Thread()
waitForReadyRead(10);
readAll
回复

使用道具 举报

4

主题

507

帖子

1082

积分

金牌会员

Rank: 6Rank: 6

积分
1082
发表于 2019-6-24 14:45:12 | 显示全部楼层
纠正一下waitForReadyRead(-1),并不是睡眠,而是无限循环查看读buf有没有新的数据
没必要一直查的
  1. ThreadFun{

  2. if(waitForReadyRead(10)){
  3. readall
  4. }
  5. else{
  6. sleep(10);
  7. }

  8. }
复制代码


回复

使用道具 举报

0

主题

2

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2019-6-24 15:28:27 | 显示全部楼层
3楼正解
waitForReadyRead(10);设置一个超时等待时间,如果没有串口数据导致超时退出,然后线程中继续下一次循环,可以在此时加入退出线程处理。
==============================
while(1)
{
//串口关闭的场合,线程退出
if(!serial_port_open)
{
break;
}

if(waitForReadyRead(10))
{
readall
}
else
{
sleep(10);
}
}
}
回复

使用道具 举报

18

主题

470

帖子

990

积分

高级会员

Rank: 4

积分
990
 楼主| 发表于 2019-6-24 15:44:55 | 显示全部楼层
引用1楼不易易的回复:1、改成异步read
2、可以试试socket强制断开。比如soket.abort()

谢谢回复!

方法1当然是可以的,之前就是这么干的,用的那个串口的信号槽,在槽里面去读数据,当然这样也就不用专门开个线程。
不过就当做是学习吧,我很想换个方法试试。因为是从非GUI的领域转过来搞QT的,开个线程专门读取阻塞方式的串口并解析数据,代码已经非常成熟了。所以也想把QT上串口也做成之前那种。

方法2可以试试。

再次谢谢!
回复

使用道具 举报

18

主题

470

帖子

990

积分

高级会员

Rank: 4

积分
990
 楼主| 发表于 2019-6-24 15:49:50 | 显示全部楼层
引用3楼走好每一步的回复:纠正一下waitForReadyRead(-1),并不是睡眠,而是无限循环查看读buf有没有新的数据
没必要一直查的

  1. ThreadFun{

  2. if(waitForReadyRead(10)){
  3. readall
  4. }
  5. else{
  6. sleep(10);
  7. }

  8. }
复制代码



引用3楼走好每一步的回复:纠正一下waitForReadyRead(-1),并不是睡眠,而是无限循环查看读buf有没有新的数据
没必要一直查的

  1. ThreadFun{

  2. if(waitForReadyRead(10)){
  3. readall
  4. }
  5. else{
  6. sleep(10);
  7. }

  8. }
复制代码


谢谢两位的回复!

之前粗略的看了下waitForReadyRead(),不知道waitForReadyRead()原来是内部查询方式,我得再看看。
如果是内部查询的话,倒有些违背我最开始的宗旨了,我就是想节省CPU的资源,不用轮询,又可以显式的线程处理才这么写代码的。




回复

使用道具 举报

18

主题

470

帖子

990

积分

高级会员

Rank: 4

积分
990
 楼主| 发表于 2019-6-24 15:50:36 | 显示全部楼层
引用4楼zhangxiuyuan的回复:3楼正解
waitForReadyRead(10);设置一个超时等待时间,如果没有串口数据导致超时退出,然后线程中继续下一次循环,可以在此时加入退出线程处理。
==============================
while(1)
{
//串口关闭的场合,线程退出
if(!serial_port_open)
{
break;
}

if(waitForReadyRead(10))
{
readall
}
else
{
sleep(10);
}
}
}


漏了
回复

使用道具 举报

4

主题

507

帖子

1082

积分

金牌会员

Rank: 6Rank: 6

积分
1082
发表于 2019-6-24 16:08:45 | 显示全部楼层
waitForReadyRead
这个函数名字取的不太恰当,之前我也一直以为是等待信号,会把线程挂起。
后面查了源码才知道是在一个死循环里不断地轮训读buf是否有新的数据进来,超时就跳出循环。
回复

使用道具 举报

18

主题

470

帖子

990

积分

高级会员

Rank: 4

积分
990
 楼主| 发表于 2019-6-24 17:02:21 | 显示全部楼层
引用8楼走好每一步的回复:waitForReadyRead
这个函数名字取的不太恰当,之前我也一直以为是等待信号,会把线程挂起。
后面查了源码才知道是在一个死循环里不断地轮训读buf是否有新的数据进来,超时就跳出循环。

感谢提醒!
另外想问一下怎么找waitForReadyRead源码看,刚还找过没找到。看了QTCreate帮助里的函数描述也确实看不出什么。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|mysql5.com Inc. ( 闽ICP备17002856号-1 )

GMT+8, 2020-1-28 11:59 , Processed in 0.056181 second(s), 18 queries .

Powered by MySQL5.com X3.4

© 2003-2019 MySQL5.com.

快速回复 返回顶部 返回列表