adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
453 stars 340 forks source link

FT232H and using Adafruit-Blinka with Multiprocessing #695

Closed LanXtai closed 1 year ago

LanXtai commented 1 year ago

Hi ! I tried using Adafruit-Blinka with Multiprocessing on Windows 10, Python 3.9, and got an unexpected error. First, here is a working minimal code, without Blinka :

from fonction_file import fonction
from multiprocessing import Process
from time import sleep

def minimal_fonction :
    nb=5
    process = Process(target=fonction, args=(nb,))
    process.start()
    sleep(0.5)
    print("main")
    for i in range(nb) :
        sleep(1)
        print("main", flush=True)

fonction being in a separate file fonction_file.py :

import time

def fonction(nb) :
    for i in range(nb):
        print("yolo", flush=True)
        time.sleep(1)

So far, it works just fine, but I need to go further and use an FT232H with Adafruit-Blinka (the idea is, as a beginning, to blink a LED as a process). But as soon as I change my fonction_file.py into

import time
import board
from digitalio import DigitalInOut, Direction

def fonction(nb) :
    for i in range(nb):
        print("yolo", flush=True)
        time.sleep(1)

(even with only the import board line, or only with the from digitalio import DigitalInOut, Direction one), I get the following error :

pyftdi.ftdi.FtdiError: UsbError: [Errno None] b'libusb0-dll:err [claim_interface] could not claim interface 0, win error: Impossible de cr\xe9er un fichier d\xe9j\xe0 existant.\r\n'

even though I didn't use the packages in my process. However, doing

from fonction_file import fonction2
from multiprocessing import Process
from time import sleep

def minimal_fonction2() :
    process = Process(target=fonction2())
    process.start()
    sleep(0.5)
    print("main")
    for i in range(5) :
        sleep(1)
        print("main", flush=True)

with fonction2being defined as :

import time
import board
from digitalio import DigitalInOut, Direction

def fonction() :
    for i in range(5):
        print("yolo", flush=True)
        time.sleep(1)

works just fine ! The difference is around the arguments : where fonction (called with target=fonction) has one argument, passed with args=(nb,), fonction2 doesn't need any argument and is called with target=fonction2(). Is there any way to pass arguments to a method in a process while using Adafruit-Blinka ? Thanks !

makermelissa commented 1 year ago

I haven't used multiprocessing. However doing a google search, I found this (https://stackoverflow.com/questions/72557549/pyftdi-issue-with-multiprocessing), which sheds a bit more light on the issue. It appears multiprocessing when using arguments causes multiple imports which makes that error display, which probably wouldn't be a problem in most other instances.

Is it possible to use a try/except block to get past the error?

@caternuson do you have any other ideas? Like is it possible to have it automatically catch the error and return the initialized interface instead of it trying to reinitialize the interface?

caternuson commented 1 year ago

Unknown. I think short answer here is multiprocessing is not generally supported. It might work to do as you are suggesting, but then other multithread issues might crop up. It'd take work to test and investigate.

makermelissa commented 1 year ago

Sounds good. I'm going to close this as unsupported.