前文:

signal-slot:python版本的多进程通信的信号与槽机制(编程模式)的库(library) —— 强化学习ppo算法库sample-factory的多进程包装器,实现类似Qt的多进程编程模式(信号与槽机制) —— python3.12版本下成功通过测试

信号与槽机制,是C++的Qt框架提出的一种并行编程模式,实际上是对原生的并行编程模式进行了一定的封装和包装,是wrap操作。

编程语言原生的并行编程模式,一般是创建多个子进程,每个子进程均拥有一个以上的通信队列,各个进程间的通信通过进程队列进行;如果一个进程想要调用另一个进程中的某个函数,并传递给其参数,那么就在通信队列中传入需要调用对方进程的具体函数名和参数,然后对方进程从队列中取出该函数名和具体参数,并按此执行,这就是不使用Qt信号与槽机制包装之前的原生并行编程通信的模式。但是使用原生的并行通信编程模式其编码比较繁琐,尤其对于一些通信场景比较复杂的情况,往往会因为过多的编码导致逻辑混乱而不利于维护,因此Qt框架提出了信号与槽机制编码模式。

简单的说,也就是在不同的对象中实现了signal函数和slot函数,在不同对象实例化后将信号发送方的signal函数注册到信号接收方的slot函数上,这个操作一般使用connection函数,完成了该函数操作实际上就是完成了signal函数对应的接收方的队列的注册,也就是说在发送方调用signal函数时会自动把自身的函数名和需要调用的对方函数名以及参数指定到接收方的队列上。

在这个项目中对发送方和接收方都需要设置循环事件对象,每个循环事件都相当于一个进程,这个进程会不断的循环执行取队列操作,并根据队列中取出的被调用函数及参数进行调用。需要注意的是,该项目的实现是需要在主进程中实现所有声明的,也就是将signal函数注册到slot函数上是在主进程中实现的,也就是connection函数操作只能在主进程中实现。虽然项目实现signal和slot的注册,并且connection可以随时进行,但是所有的声明和connection操作必须在主进程中执行。

每个带有signal和slot函数的对象都必须绑定到一个EventLoop事件上,不同的EventLoop事件运行在不同的进程上,实际上由于EventLoop事件是一个单独的进程,而所有的signal、slot、connection声明都是在主进程中进行的,因此子进程的EventLoop事件启动后会将主进程中与其绑定的带有signal和slot函数的对象copy到子进程中(spawn方式的子进程生成方式,会将主进程中的一切对象全部copy到子进程中,因为信号与槽机制中对被调用对象的标识是使用身份ID字符串的,因此即使在主进程中进行的注册声明,在copy到子进程中依旧可以毫无影响的同样进行调用,只不过具体执行时是在子进程中)。

也正因为该项目的这种实现方式(子进程启动后copy父进程中的所有对象),那么其实任意一个运行在子进程中的对象在主进程中都是有着一个同样的影子对象的,因此我们在主进程中调用一个绑定在子进程中的对象的signal函数时其实并不是在调用运行在子进程中的对象,而是调用其在主进程中的影子对象,因此可以认为所有在主进程中完成connection的signal函数并且其信号发射操作(emit函数)也是在主进程中进行的,那么气emit操作就是在主进程中进行的;同时由于子进程的copy默认操作,那么在子进程中对绑定到子进程上的对象进行emit操作其实是在子进程中进行的;因此总的来说,signal和slot的connection操作必须在主进程中进行声明和执行,但是emit操作在哪里执行是需要看其被调用的对象绑定到哪个进程上的。

信号与槽机制的核心原理,就是进程和进程间通信时通过队列实现的,一个进程中的对象如果调用另一个进程中的某个对象的函数,其实就是把被调用对象的ID字符串和被调用函数的ID字符串以及参数一并通过队列发送给被调用的进程。

需要注意,signal-slot库通过在主进程中实现对signal和slot的connection的声明和注册,其实就是将slot函数的对象ID字符串及通信队列和函数ID字符串绑定给signal函数,这样在signal函数进行emit操作时其实质就是将信息message连同slot函数的对象ID字符串和函数ID字符串发送给slot函数的对象的通信队列。由于每个slot函数所属对象的队列都是在主进程中声明并绑定在各自的对象内的,而EventLoop都是在所有声明完成后在生成子进程时自动copy父进程的所有对象到子进程中的,因此所有的队列都是在主进程和子进程之间的,并没有子进程之间的队列,由于这种声明注册、绑定、子进程copy方式实现的信号与槽机制,只将每个EventLoop的队列暴露给自身,难以实现子进程之间的通信。

PS. 可以说,这个项目的实现比较复杂,逻辑也比较混乱,虽然可以实现作者的设定目标,但是这个逻辑搞的如此混乱也是难以继续维护的,可以说这个项目就是论文代码的副产品,并不具有延续性。

项目作者给出的待完善的功能:

It is currently impossible to connect a slot to a signal if emitter and receiver objects belong to event loops already running in different processes (although it should be possible to implement this feature). Connect signals to slots during system initialization.

简单的说,就是需要先connection设置好以后才可以start,如果start了以后再connection就不会有限,这个原因就是上面刚才说的这个子进程启动的copy操作,如果子进程启动以后自然是不会再copy父进程中后生成的对象的设置了。

(续)signal-slot:python版本的多进程通信的信号与槽机制(编程模式)的库(library) —— 强化学习ppo算法库sample-factory的多进程包装器,实现类似Qt的多进程编程模式(信号与槽机制) —— python3.12版本下成功通过测试的更多相关文章

  1. Python中根据库包名学习使用该库包

    目录 Python库包模块 import 语句 from-import 语句 搜索路径 PYTHONPATH 变量 命名空间和作用域 查看模块中所有变量和函数,以及查看具体函数的用法 globals( ...

  2. python类库32[多进程通信Queue+Pipe+Value+Array]

    多进程通信 queue和pipe的区别: pipe用来在两个进程间通信.queue用来在多个进程间实现通信. 此两种方法为所有系统多进程通信的基本方法,几乎所有的语言都支持此两种方法. 1)Queue ...

  3. QT写hello world 以及信号槽机制

    QT是一个C++的库,不仅仅有GUI的库.首先写一个hello world吧.敲代码,从hello world 写起. #include<QtGui/QApplication> #incl ...

  4. 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)

    使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...

  5. Qt信号槽的一些事 Qt::带返回值的信号发射方式

    一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值.那么如果我们发出这个信号想获取一个返回值怎么办呢? 两个办法:1.通过出参形式返回,引用或者指 ...

  6. 使用 C++11 编写类似 QT 的信号槽——上篇

    了解 QT 的应该知道,QT 有一个信号槽 Singla-Slot 这样的东西.信号槽是 QT 的核心机制,用来替代函数指针,将不相关的对象绑定在一起,实现对象间的通信. 考虑为 Simple2D 添 ...

  7. QT窗体间传值总结之Signal&Slot

    在写程序时,难免会碰到多窗体之间进行传值的问题.依照自己的理解,我把多窗体传值的可以使用的方法归纳如下: 1.使用QT中的Signal&Slot机制进行传值: 2.使用全局变量: 3.使用pu ...

  8. QT 中 关键字讲解(emit,signal,slot)

    Qt中的类库有接近一半是从基类QObject上继承下来,信号与反应槽(signals/slot)机制就是用来在QObject类或其子类间通讯的方法.作为一种通用的处理机制,信号与反应槽非常灵活,可以携 ...

  9. Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型

    Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: ​ ​ ​ 每个对象都对应于一个可称为" 互斥锁&qu ...

  10. 《ASP.NET MVC4 WEB编程》学习笔记------Entity Framework的Database First、Model First和Code Only三种开发模式

    作者:张博出处:http://yilin.cnblogs.com Entity Framework支持Database First.Model First和Code Only三种开发模式,各模式的开发 ...

随机推荐

  1. HP惠普战66电源黄灯闪烁无法充电

    HP惠普战66电源黄灯闪烁无法充电 TYPE-C PD 无法充电. 解决办法:关机状态下,拔除外部设备,长按电源键30秒以释放主板静电,再插电源线可以开机.

  2. 硬件开发笔记(十七):RK3568底板电路串口、485、usb原理图详解

    前言   原理图有一些常用电路.  本篇就将集中常用电路分析完,如uart口,涉及usart串口.rs485.usb口.   串口   串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接 ...

  3. asp.net上传Excel文件并读取内容,自定义上传控件样式

    一.页面增加上传控件,并在上传时判断是否是Excel文件(根据后缀名判断): 1 <table> 2 <tr> 3 <td> 4 <span style=&q ...

  4. Go变量作用域精讲及代码实战

    关注作者,复旦AI博士,分享AI领域与云服务领域全维度开发技术.拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕博,复旦机器人智能实验室成员,国家级大学生赛事评审专家,发表多篇 ...

  5. java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $

    java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $ pack ...

  6. pytest-allure 命令生成的报告,test body 没有具体的参数和日志

    run.py: pytest.main([命令参数执行]),pytest命令执行完毕后,使用os.system()执行allure的命令 原因: 使用了命令:os.system('allure gen ...

  7. 实训day2

    HTML基本介绍 编辑网页的语言,超文本标记语言,是迄今为止网络上应用最为广泛的语言,也是抱成网页文档的主要语言.HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字.图形.动画.声 ...

  8. TRL(Transformer Reinforcement Learning) PPO Trainer 学习笔记

    (1)  PPO Trainer TRL支持PPO Trainer通过RL训练语言模型上的任何奖励信号.奖励信号可以来自手工制作的规则.指标或使用奖励模型的偏好数据.要获得完整的示例,请查看examp ...

  9. 嵌入式测试手册——基于NXP iMX6ULL开发板(2)

    基于测试板卡:创龙科技TLIMX6U-EVM是一款基于NXP i.MX 6ULL的ARM Cortex-A7高性能低功耗处理器设计的评估板,由核心板和评估底板组成.核心板经过专业的PCB Layout ...

  10. welcome to chifan-duck's blog

    博主简介 截至至 2024 博主事一名初二学生. 为什么开博客园 因为博主是一名 Oier. 博客内容 OI 知识(科技)的普及 & 题解 为什么叫 chifan-duck ? 原本博主再各大 ...