¿Cómo implementar subprocesos para ejecutar dos comandos de shell bash en python?

Tengo que grabar un archivo wav y al mismo tiempo tengo que analizarlo con sox. Estoy usando el archivo de tipo fifo para esta operación.

Así que aquí necesito comenzar 2 hilos al mismo tiempo, pero incluso si uso los hilos no puedo lograr lo que quiero hacer. Siempre uno ejecutando primero y luego el otro. Quiero que estén en paralelo para que pueda hacer algunas cosas.

#this should be in one thread def test_wav(self): """ analyze the data """ bashCommand = "sox {} -n stat".format(self.__rawfile) while self.__rec_thread.is_alive(): process = subprocess.Popen(bashCommand.split(),stdout=subprocess.PIPE,stderr=subprocess.PIPE) wav_output = process.communicate()[1] #sox outputs the details in stderr #do something and return #this should be in another thread def record_wav(self): bashCommand = "arecord -d 10 -c 2 -r 48000 -f S32_LE > {}".format(self.__rawfile) pid = subprocess.Popen(bashCommand.split()) pid.wait() if pid.returncode != 0: raise RecordException("Failed while recording with error {}".format(pid.returncode)) 

Intenté el siguiente código para convertirlos en subprocesos, pero fallé (siempre uno ejecutándose primero y luego el otro. Quiero que estén en paralelo para poder hacer algunas cosas). Importado from threading import Thread

 self.__rec_thread = Thread(target = self.record_wav()) amp_thread = Thread(target = self.test_wav()) self.__rec_thread.start() amp_thread.start() 

EDITAR: Primero se ejecuta el registro (tarda un mínimo de 10 segundos debido a la opción -d 10), la función por completo y luego la función wav de prueba. Es como llamarlos uno tras otro.

 ... target = self.record_wav() ... 

está llamando a record_wav() : se ejecuta inmediatamente, y el progtwig no continúa hasta que record_wav() . Casi siempre desea pasar un objeto de función (o método) a target= , casi nunca el resultado de ejecutar la función / método. Así que solo pierden los paréntesis:

 ... target = self.record_wav ... 

Si es probable que uses python3, puedes usar asyncio para ejecutar el comando de shell de forma goroutines.

 import asyncio import sys async def execute(command, cwd=None, shell=True): process = await asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=cwd, shell=shell) std_out, std_err = await process.communicate() error = std_err.decode().strip() result = std_out.decode().strip() print(result) print(error) return result if sys.platform == "win32": loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) else: loop = asyncio.get_event_loop() try: loop.run_until_complete( asyncio.gather(execute(["bash", "-c", "echo hello && sleep 2"]), execute(["bash", "-c", "echo ok && sleep 1"]))) except Exception as e: raise e finally: loop.close()