• 2459阅读
  • 14回复

[提问]QT中如何实现两个线程分别接收和发送数据? [复制链接]

上一主题 下一主题
离线mugua001
 

只看楼主 倒序阅读 楼主  发表于: 2021-09-01
最近在学习Qt时,做了一个TCPSOCKET的应用。
想实现服务端:
线程接收数据,然后 交给 子线程处理并在子线程中回复给客户端;   (收、发两条线);
结果,始终报:Cannot create children for a parent that is in a different thread;数据也能发送成功,但做为程序猿,不对对异常视而不见……但始终没找到解决办法……

有大神告诉我,将监听、接收、发送,全丢进子线程,问题来了:收发还是在同一个线程中。
我想 将收、发分在两个线程中……请问哪位实现成功了,来指点迷津,谢谢。
(我这个想法,不知道 是不是伪科学?  见网上有人    说是QTcpSocket的创建和使用要在同一个线程里……那我这想法就是错误的了?


离线20091001753

只看该作者 1楼 发表于: 2021-09-02
线程之间应该“各家自扫门前雪”,进而用 信号槽 来处理协同问题。

所以:

不应该直接在 QThread 里直接调用 QTcpSocket 的 write,因为它俩不是同一个线程。

也不应该在 B线程里,创建 属于 A线程的 QObject 的子实例(Qt 就会提示你发的这个异常)。

QThread 希望 QTcpSocket 能发送数据,就应该是把数据用信号槽的方式投递给 QTcpSocket,后者在自己的线程里发送。
(づ ̄ 3 ̄)づ
离线yuyu414

只看该作者 2楼 发表于: 2021-09-02
socket的收发应该在同一个线程,数据处理用另一个线程
离线hank119

只看该作者 3楼 发表于: 2021-09-02
收到的数据放在缓存里面,写数据加入一队列。处理数据另起一个线程!一般都这样的吧
离线mugua001

只看该作者 4楼 发表于: 2021-09-02
回 yuyu414 的帖子
yuyu414:socket的收发应该在同一个线程,数据处理用另一个线程 (2021-09-02 09:56) 

非常感谢!

同时也感谢楼上的各位大神!


看来我之前的想法,是错误的了。

以后知道这个路线了:收、发在一个线程,处理环节可以单独一个线程;。
离线zhaoxg

只看该作者 5楼 发表于: 2021-09-03
个人感觉,看怎么方便,一个接收数据,一个处理,完成后发送,完全可以三个线程处理各不相干,处理起来思路比较清晰
离线mugua001

只看该作者 6楼 发表于: 2021-09-04
回 zhaoxg 的帖子
zhaoxg:个人感觉,看怎么方便,一个接收数据,一个处理,完成后发送,完全可以三个线程处理各不相干,处理起来思路比较清晰 (2021-09-03 01:11) 

啊?这么行吗?……
接收、发送不在一个线程的话,始终报:Cannot create children for a parent that is in a different thread;
离线wwwfffhhh

只看该作者 7楼 发表于: 2021-09-04
我想应该是接收和发送应该在同一个线程,实际就是应该在建立socket对象的线程,然后处理数据可以放到另外的线程中
在线fsu0413

只看该作者 8楼 发表于: 2021-09-04
首先 QThread有一个大坑,就是QThread本身也是QObject,且QThread本身永远不在QThread自身表示的线程中
QThread的构造函数中构造的变量是QThread->thread()线程上的,而不是这个QThread本身的

然后再说你的问题。

1. QIODevice::write并不是槽函数,不能直接slot,需要给个槽函数然后connect。
2. 如果不需要特别高的并发的话,完全可以把两个QTcpSocket放在同一个线程里,然后就可以直接调用write了。(事实上我自己的程序,并发不是特别高,几十个QTcpSocket都在一个线程。。。。)
离线mugua001

只看该作者 9楼 发表于: 2021-09-04
回 fsu0413 的帖子
fsu0413:首先 QThread有一个大坑,就是QThread本身也是QObject,且QThread本身永远不在QThread自身表示的线程中
QThread的构造函数中构造的变量是QThread->thread()线程上的,而不是这个QThread本身的
然后再说你的问题。
....... (2021-09-04 13:13) 

嗯。并发不高可以一个线程;

我想学习构一个日志收集的程序:瞬间有数十主机向 日志 收集端连接、传送数据,处理完再发出……

才想着 一个线程专门接收,一个线程专门处理和发送(来自某个Client)数据;每个Client来的请求,临时创建一个线程,回复完即销毁线程;
在线fsu0413

只看该作者 10楼 发表于: 2021-09-11
回 mugua001 的帖子
mugua001:嗯。并发不高可以一个线程;
我想学习构一个日志收集的程序:瞬间有数十主机向 日志 收集端连接、传送数据,处理完再发出……
....... (2021-09-04 13:57) 

换用线程池吧。。。。。

只看该作者 11楼 发表于: 2022-01-04
解决了吗请问?我也有这个困扰
离线zhaoxg

只看该作者 12楼 发表于: 2022-01-21
感觉QThread很坑!

用QT处理线程编程,mo'veThread还是首选,用QThread子类化感觉有点啰嗦
离线zhaoxg

只看该作者 13楼 发表于: 2022-01-22
子类化QThread的方法,就是重写了QThread中的run()函数,在run()函数中定义了需要的工作。这样的结果是,我们自定义的子线程调用start()函数后,便开始执行run()函数。如果在自定义的线程类中定义相关槽函数,那么这些槽函数不会由子类化的QThread自身事件循环所执行,而是由该子线程的拥有者所在线程(一般都是主线程)来执行。如果你不明白的话,请看,第二个例子中,子类化的线程的槽函数中输出当前线程的ID,而这个ID居然是主线程的ID!!事实的确是如此,子类化的QThread只能执行run()函数中的任务直到run()函数退出,而它的槽函数根本不会被自己的线程执行。
离线zhaoxg

只看该作者 14楼 发表于: 2022-01-22
moveToThread方法,是把我们需要的工作全部封装在一个类中,将每个任务定义为一个的槽函数,再建立触发这些槽的信号,然后把信号和槽连接起来,最后将这个类调用moveToThread方法交给一个QThread对象,再调用QThread的start()函数使其全权处理事件循环。于是,任何时候我们需要让线程执行某个任务,只需要发出对应的信号就可以。其优点是我们可以在一个worker类中定义很多个需要做的工作,然后发出触发的信号线程就可以执行。相比于子类化的QThread只能执行run()函数中的任务,moveToThread的方法中一个线程可以做很多不同的工作(只要发出任务的对应的信号即可)。
快速回复
限100 字节
 
上一个 下一个