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

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

from multiprocessing import Queue
from multiprocessing import Process
import os
import serial
from serial.tools import list_ports
from time import sleep

displayMessages = Queue()
modemPort = None

def processDisplayMessages(displayMessages):
    while True:
        msg = displayMessages.get()  #should halt until message in queue
        print msg

def 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:\python27\lib\multiprocessing\process.py", line 258, in _bootstrap
    self.run()
  File "c:\python27\lib\multiprocessing\process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\matthew.parets\Documents\..Development\RaspberryPi\windows\seri
alRecvPrototype.py", line 27, in processIncomingSerialMessages
    line = modemPort.readline()
  File "c:\python27\lib\site-packages\serial\serialwin32.py", line 246, in read
    if not self.hComPort: raise portNotOpenError
AttributeError: '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之后有一个无限循环.从什么意义上说,这违反了“接收过程必须始终保持活动”?

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

上一篇:将Lambda表达式作为参数传递给方法?


下一篇:javascript-如何使用功能参数作为对象的点表示法中的属性