Многопроцессорность с сокетами в python - PullRequest
0 голосов
/ 08 июля 2020

Я застрял над этой проблемой уже несколько недель и хотел бы получить помощь в этом. У меня есть 3 малиновых писца, которые берут данные и отправляют данные другому пи для анализа (среди прочего). Когда один raspberry pi отправляет данные, следующий код отлично подходит для получения данных о процессе и одновременного запуска основного процесса, но когда я добавляю больше, модуль многопроцессорности (в сочетании с PyBluez), похоже, выходит из строя. Основной процесс зависает, пока не будут подключены все сокеты. Я думаю, это из-за строки server_sock.listen(inputs[1]). Похоже, это приводит к зависанию выполнения основного процесса до тех пор, пока не будут подключены все отправляющие данные пи.

В своих исследованиях я столкнулся с multiprocessing.set_start_method('spawn', force=True) как возможное решение этой проблемы, но не могу похоже, это тоже работает. Я также пробовал использовать многопоточность, что приводило к всевозможным ошибкам. Из того, что я могу сказать, что многопроцессорность должна работать, я не могу понять, почему основной процесс зависает. Ошибка не возникает, и когда все малиновые писи подключены, он работает должным образом. Если кто-нибудь знает, почему это происходит, это будет огромной помощью!

import multiprocessing
from bluetooth import *
import time
from pylab import *
import datetime
import socket
from decimal import *
import os
import subprocess as sp
import pyautogui
from multiprocessing import Process
# This function is ran on each process, and should collect the data being sent and analyze it
def func1(inputs,d):
    try:
        print("Starting")
        server_sock=BluetoothSocket(RFCOMM)
        server_sock.bind(("",inputs[1]))
 # I believe this is the problematic line
        server_sock.listen(inputs[1])
        server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, inputs[1])
        client_sock,address = server_sock.accept()
        print("Accepted connection  from ", inputs[0])
        Scan = 0
        Fails = 0
        ReaderIDInter2 = inputs[0].replace('B8:27:EB:','')
        ReaderID = ReaderIDInter2.replace(':','')
        while True:
            # Receiving Bluetooth Data
            try:
                databytes = client_sock.recv(1024)
                data = list(databytes)
            except:
                continue
            lst2 = []
            for i in range(0,len(data)-1,2):
                lst2.append(float(str(data[i]) + '.' + str(data[i+1])))
            MinFreq = lst2[0]
            Minx = lst2[1]/10
            d[inputs[1]-1] = Minx
            # Does stuff with the values collected(unimportant for this post)
    except:
        server_sock.close()
        client_sock.close()
        print("Unexpected Error:", sys.exc_info()[0])
        print(str(ReaderID) + " not connected.")
        print("Attempting to reconnect")
        
try:
 
    # This portion sets up the bluetooth devices and starts all processes
    BluetoothMAC = list(["B8:27:EB:33:B1:78","B8:27:EB:5E:AD:48","B8:27:EB:BE:23:12"])
    ReaderIDInter = []
    ReaderID = []
    for i in range(len(BluetoothMAC)):
        ReaderIDInter.append(BluetoothMAC[i].replace('B8:27:EB:',''))
        ReaderID.append(ReaderIDInter[i].replace(':',''))
    RealLen = 0
    for i in range(len(BluetoothMAC)):
        if BluetoothMAC[i] != None:
            RealLen += 1
    
    #Setting up bluetooth connections (This is the important part for this post)
    p = []
    x = []
    if __name__ == '__main__':
        manager = multiprocessing.Manager()
        d = manager.list(range(len(BluetoothMAC)))
        for i in range(RealLen):
            t3=time.time()
            port = i+1
            Fact = False
            p.append('p' + str(port))
            x.append('x' + str(port))
            inputs = (BluetoothMAC[i],port,TopicPath)
            try:
                time.sleep(1)
                p[-1] = Process(target=func1, args=(inputs,d))
                p[-1].start()
            except:
                print("Still not connected")
        Time = 0
    while True:
        try:
            t3 = time.time()
            print(d)
            # Restarts the process if it has stopped (readers rebooting etc.)
            for i in range(len(p)):
                if p[i].is_alive() == False:
                    inputs = (BluetoothMAC[i], i+1, TopicPath)
                    p[i] = Process(target=func1, args=(inputs,d))
                    p[-1].start()
                else:
                    continue
            # This portion updates a screen that is on the receiving pi every minute (not important for this post)
            while t4-t3 < 60:
                time.sleep(1)
                t4 = time.time()
        except:
            continue
except:
    print("Unexpected Error:", sys.exc_info()[0])
    client_sock.close()
    server_sock.close()
    raise
...