关于ZAKER 融媒体解决方案 合作 加入

python- 使用串行对象作为参数的多进程

CocoaChina 2019-11-23

我在使用Python时遇到问题 , 并将串行对象作为参数传递给单独的进程 . 该程序正在 Windows 8 中运行 , 因此不能使用全局变量 .

from multiprocessing import Queuefrom multiprocessing import Processimport osimport serialfrom serial.tools import list_portsfrom time import sleepdisplayMessages = Queue ( ) modemPort = Nonedef processDisplayMessages ( displayMessages ) : while True: msg = displayMessages.get ( ) #should halt until message in queue print msgdef processIncomingSerialMessages ( modemPort, displayMessages ) : while True: line = modemPort.readline ( ) displayMessages.put ( line ) def main ( ) : print "Serial Send Test" Process ( target=processDisplayMessages, args = ( displayMessages, ) ) .start ( ) modemPort = serial.Serial ( 'COM5', 57600, timeout=0.9 ) # open first serial port Process ( target=processIncomingSerialMessages, args = ( modemPort, displayMessages ) ) .start ( ) print "Back from launch" sleep ( 0.1 ) if __name__ == '__main__': main ( )

程序运行时 , 出现以下错误:

Process Process-2:Traceback ( most recent call last ) : File "c:python27libmultiprocessingprocess.py", line 258, in _bootstrap self.run ( ) File "c:python27libmultiprocessingprocess.py", line 114, in run self._target ( *self._args, **self._kwargs ) File "C:Usersmatthew.paretsDocuments..DevelopmentRaspberryPiwindowsserialRecvPrototype.py", line 27, in processIncomingSerialMessages line = modemPort.readline ( ) File "c:python27libsite-packagesserialserialwin32.py", line 246, in read if not self.hComPort: raise portNotOpenErrorAttributeError: 'Serial' object has no attribute 'hComPort'

如果我将串行端口 ( modemPort ) 的开放位置设置为 processIncomingSerialMessages 的第一行 , 则程序运行正常 . 问题是我需要从调制解调器解耦输入和输出 , 因此需要将串行对象作为参数传递 . 而且 Python 似乎不喜欢那样 .

有人可以看到我犯的错误吗 , 或者有人可以建议替代方法?

我无法运行此代码 , 但是如果它起作用了 , 我会感到惊讶:跨进程传递的参数的工作方式是:在发送端对参数对象进行腌制 , 通过管道或套接字在进程之间发送腌制字符串 , 然后将其解开接收方的字符串 . 我不知道任何打开的 I / O 种类的对象都可以工作的情况 ( 文件 , 套接字 , 管道… ) . I / O 类对象不仅具有内部数据状态 , 而且还连接到 Python 本身未实现的资源 . 泡菜只是原始字节流 .

您已经确定必须在工作进程中打开串行端口 . las, 我不知道 " 我需要从调制解调器解耦输入和输出 " 的含义 , 因此很难提出解决方法 . 但是 , 我敢肯定 , 如果您接受已经发现的困难方法 , 就可以弄清楚:跨进程传递一个开放的串行对象永远不会起作用 .

也就是说 , 您可以深入研究各种酸洗协议 , 并使用自定义的酸洗 / 酸洗代码构建自己的类 , 该代码在酸洗时会 ( 重新 ) 打开一个串行对象 . 这将是一种精心制作的方法 , 可以隐藏原本可以在工作进程中 ( 重新 ) 打开串行对象的简单代码 .

编辑:问答

And again windows doesn ’ t offer the easy way out of global variables, so I ’ m stuck with a single process handing both send and receive.

" 全局变量 " 可能对您没有帮助 . 我假设您已经记住了 fork ( ) , 但是在 fork ( ) 之间也没有任何共享:子进程看到父进程地址空间的副本 . I / O O 头通常也无法正常工作 .

Does Python provide a way to pass a value by reference, or a reference value to a process? I have tried add the serial object to lists and sets with the same results. Again, does Python provide something like an Object or an Array from Java where I could get a reference through without it being "Pickled"?

在所有现代 OS 中 , 进程之间都有很高的隔离墙 . 为了使所有内容真正跨进程共享 , 您需要使用完全为此构建的类型 , 或者使用操作系统的 " 共享内存 " 功能 .

您可以阅读有关 multiprocessing.sharedctypes 的文档 , 其中提供了使用共享 ( 跨进程 ) 内存的方法 . 但是 , 正如文档警告所示:

Note

Although it is possible to store a pointer in shared memory remember that this will refer to a location in the address space of a specific process. However, the pointer is quite likely to be invalid in the context of a second process and trying to dereference the pointer from the second process may cause a crash.

这是行不通的 . 这不是编程语言问题 , 而是操作系统问题 . sharedctypes 对于 int 和 float 数组之类的东西很有用 .

For this application to work ( live telemetry ) the receive process has to remain live at all times.

抱歉 , 我没有在上下文中关注 . 您在问题中说:" 如果我将串行端口 ( modemPort ) 的开放位置放置为 processIncomingSerialMessages 的第一行 , 则程序运行正常 ." processIncomingSerialMessages 之后有一个无限循环 . 从什么意义上说 , 这违反了 " 接收过程必须始终保持活动 "?

在您显示的代码中 , 无论是在工作进程中还是在主进程中打开串行端口 ( 如果后者确实起作用 ) , 似乎都没有什么区别 , 实际上 , 您说过 , 如果工作了 , 则可以正常工作它是前一种方式 . 那么 , 这样做到底有什么问题呢?确实 , 为什么要为此全部使用工作者进程?您显示的主程序在启动两个工作程序之后什么都没有做 ( 除了睡眠十分之一秒 ) , 那么为什么不让主程序成为 " 接收过程 " 呢?

以上内容由"CocoaChina"上传发布 查看原文
相关标签 windows对象参数

觉得文章不错,微信扫描分享好友

扫码分享