简体   繁体   English

具有不确定进程数的多处理

[英]Multiprocessing with undetermined number of processes

I'm far from being adapt in python and since 3 days I'm trying to figure out how to properly work with multiprocessing, but now I hit a dead and and need some assistance. 我远没有适应python,因为3天我试图弄清楚如何正确地处理多处理,但现在我已经死了,需要一些帮助。

Basically what the program is supposed to do, is controlling different segments of an LED strip from multiple (seni-random) inputs at the same time. 基本上该程序应该做的是同时控制LED条带的不同段与多个(seni-random)输入。 Therefore I came to the conclusion that I probably need to use multiprocessing. 因此我得出结论,我可能需要使用多处理。

I've written a module for it using an existing module from Adafruit. 我使用Adafruit的现有模块为它编写了一个模块。 (I stripped it down for demonstration) (我把它拆下来进行演示)

import time
import RPi.GPIO as GPIO
from multiprocessing import Lock
import Adafruit_WS2801
import Adafruit_GPIO.SPI as SPI

class Pixels(object):
    def __init__(self, pixelCount, spiPort, spiDevice):
        self.l = Lock()

        self.pixels = Adafruit_WS2801.WS2801Pixels(pixelCount, spi=SPI.SpiDev(spiPort, spiDevice), gpio=GPIO)

        # Clear all the pixels to turn them off.
        self.pixels.clear()
        self.pixels.show() 

    def set_color(self, target_pixel, color=(255,0,0)):
        for k in target_pixel:
            self.l.acquire()
            self.pixels.set_pixel(k, Adafruit_WS2801.RGB_to_color( color[0], color[1], color[2] ))
            self.l.release()
        self.l.acquire()
        self.pixels.show()
        self.l.release()

    def blink_color_blank(self, target_pixel, blink_times=1, wait=0.5, color=(255,0,0)):
        for i in range(blink_times):
            self.set_color(target_pixel, color)
            time.sleep(wait)
            self.set_color(target_pixel, (0,0,0))
            time.sleep(wait)

Inside of self.pixels all the information about which LED should have which color is stored. 在self.pixels里面有关哪个LED应该存储哪种颜色的所有信息。 self.pixels.set_pixel() writes the new values to storage. self.pixels.set_pixel()将新值写入存储。 self.pixels.show() actually sends these values to the SPI-Bus. self.pixels.show()实际上将这些值发送到SPI-Bus。

Now my attempt at multiprocessing starts like this. 现在我尝试多处理就像这样开始。

from multiprocessing import Process, Manager
from multiprocessing.managers import BaseManager
import LED_WS2801

if __name__ == '__main__':
    BaseManager.register('LedClass', LED_WS2801.Pixels)
    manager = BaseManager()
    manager.start()
    inst = manager.LedClass(10,0,0)

Now my problem arises when I start a process while another is still active. 现在我的问题出现在我开始一个进程而另一个仍处于活动状态时。

    p = Process(target=inst.blink_color_blank, args=([6,7,8], 10, 0.25, (255,0,0),))
    p.start()
    p = Process(target=inst.set_color, args=([3,4,5,6],(0,255,0),))
    p.start()
    p.join()

This gives me following error: 这给了我以下错误:

Process Process-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
File "<string>", line 2, in blink_color_blank
File "/usr/lib/python2.7/multiprocessing/managers.py", line 759, in _callmethod
    kind, result = conn.recv()
EOFError

But when I do something like this, everything is fine. 但是当我做这样的事情时,一切都很好。

    p = Process(target=inst.blink_color_blank, args=([6,7,8], 10, 0.25, (255,0,0),))
    p.start()
    b = Process(target=inst.set_color, args=([3,4,5,6],(0,255,0),))
    b.start()
    p.join()
    b.join()

But I don't know my final number of processes as they get spawned by external inputs, so I need some way to control a variable number of processes. 但是我不知道我的最终进程数量是因为它们是由外部输入产生的,所以我需要一些方法来控制可变数量的进程。 My idea was to use a list like this: 我的想法是使用这样的列表:

    jobs = []

    jobs.append(Process(target=inst.set_color, args=([0,1,2],(255,0,255),)))
    jobs[0].start()

But much to my disappointment this returns with another error: 但令我失望的是,这又带来了另一个错误:

    Process Process-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
File "<string>", line 2, in set_color
File "/usr/lib/python2.7/multiprocessing/managers.py", line 755, in _callmethod
    self._connect()
File "/usr/lib/python2.7/multiprocessing/managers.py", line 742, in _connect
    conn = self._Client(self._token.address, authkey=self._authkey)
File "/usr/lib/python2.7/multiprocessing/connection.py", line 169, in Client
    c = SocketClient(address)
File "/usr/lib/python2.7/multiprocessing/connection.py", line 308, in SocketClient
    s.connect(address)
File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 2] No such file or directory

I hope I made my problem as understandable and clear as possible. 我希望我能使问题尽可能明白和清晰。 As I haven't found anything like this I guess I'm doing something fundamentally wrong. 由于我没有找到这样的东西,我想我做的事情根本就是错误的。 So would you help me out, please? 所以,你能帮帮我吗? Thank you. 谢谢。

you have to wait all child processes to finish its job, with re-asign p : 你必须等待所有子进程完成它的工作,重新设置p

p = Process(...)
p.start()
p = Process(...)
p.start()
p.join()

you are just waiting for the later one in p to finish, the error comes when master wants to terminate but the first child process is still running. 你只是等待p的后一个完成,当master想要终止但第一个子进程仍在运行时出现错误。 try this to wait for all child to finish: 试着这样等待所有孩子完成:

p1 = Process(target=inst.blink_color_blank, args=([6,7,8], 10, 0.25, (255,0,0),))
p1.start()
p2 = Process(target=inst.set_color, args=([3,4,5,6],(0,255,0),))
p2.start()
childs = [p1, p2]
while any(p.is_alive() for p in childs):
    for p in childs:
        p.join(1)

besides, there is an multiprocessing.active_children() api to get all the children of the current process, in case you really cant gather the list from the beginning. 此外,还有一个multiprocessing.active_children() api来获取当前进程的所有子进程,以防你真的无法从头开始收集列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM