Ejecución asíncrona de Python Subprocess.Popen con espera () -- python campo con subprocess campo con python-asyncio campo con python-multithreading campo con popen camp Relacionados El problema

Asynchronous execution of Python subprocess.Popen with wait()


1
vote

problema

Español

Soy nuevo en los conceptos de Python Async. Sin embargo, quiero llamar a 2 funciones secuencialmente, el pedido es lo que importa aquí:

  def func1():     p = subprocess.Popen('ffmpeg -i in.webm out.mp4')     p.wait()  def func2():     os.remove('in.webm')  func1() func2()   

Función 1 Contiene subproceso que convierte los archivos de video, y la función 2 elimina la entrada después.
Popen CON p.wait() Hace la ejecución sincrónica, pero se presenta al precio de bloquear el hilo principal.
Popen Sin p.wait() no lo bloquea, pero hace que la función 2 se llame antes de que FFMPEG completará su trabajo.

Me gustaría lograr algo similar a las promesas de JavaScript o ASYNC / AWAIT construcciones como esta:

  async func1() {     let response = await fetch('/api');     let user = await response.json();     return user; }  func2(func1());   

Suena como una tarea trivial, pero estoy perdido entre multithreading, multiprocesamiento y asyncio.
¿Cómo puedo hacer la función 2 para esperar para la salida de la función 1 sin bloquear el hilo principal?

Original en ingles

I'm new to Python async concepts. However I want to sequentially call 2 functions, the order is what matters here:

def func1():     p = subprocess.Popen('ffmpeg -i in.webm out.mp4')     p.wait()  def func2():     os.remove('in.webm')  func1() func2() 

Function 1 contains subprocess which converts video files, and function 2 deletes the input afterwards.
Popen with p.wait() does force synchronous execution but it comes at the price of blocking the main thread.
Popen without p.wait() doesn't block it but makes function 2 to get called before ffmpeg will complete its job.

I would like to achieve something similar to Javascript promises or async/await constructs like this:

async func1() {     let response = await fetch('/api');     let user = await response.json();     return user; }  func2(func1()); 

Sounds like a trivial task but I'm lost between multithreading, multiprocessing and asyncio.
How can I make function 2 to await for the output of function 1 without blocking the main thread?

              
         
         

Lista de respuestas

1
 
vote
vote
La mejor respuesta
 

para engendrar subprocesos en un programa de asintio, use Primitives de subproceso de Asyncio Que proporcionan una interfaz similar a la de subprocess , pero exponiendo a las corporaciones reservadas.

El equivalente a su ejemplo de JavaScript sería algo así:

  async def main():     # Schedule func1() to run, but don't await it. (In JavaScript     # it would be enough to just call func1().)     asyncio.create_task(func1())      print('we get here immediately')      # Await something to keep the event loop spinning - without     # this, the program would exit at this point. In real code     # this would await an exit signal, server.wait_closed(), etc.     await asyncio.Event().wait()  async def func1():     # Like in JavaScript, await suspends the current function     # until a result is available.     res = await fetch('/api1', {})     userid = (await res.json()).id     asyncio.create_task(fun2(userid))  async def func2(userid):     res = await fetch('/api2', ...userid...)     func3((await res.json()).url)  def func3(url):     print('user photo', url)  asyncio.run(main())   
 

To spawn subprocesses in an asyncio program, use asyncio's subprocess primitives which provide an interface similar to that of subprocess, but exposing awaitable coroutines.

The equivalent of your JavaScript example would be something like this:

async def main():     # Schedule func1() to run, but don't await it. (In JavaScript     # it would be enough to just call func1().)     asyncio.create_task(func1())      print('we get here immediately')      # Await something to keep the event loop spinning - without     # this, the program would exit at this point. In real code     # this would await an exit signal, server.wait_closed(), etc.     await asyncio.Event().wait()  async def func1():     # Like in JavaScript, await suspends the current function     # until a result is available.     res = await fetch('/api1', {})     userid = (await res.json()).id     asyncio.create_task(fun2(userid))  async def func2(userid):     res = await fetch('/api2', ...userid...)     func3((await res.json()).url)  def func3(url):     print('user photo', url)  asyncio.run(main()) 
 
 
         
         

Relacionados problema

1  Problemas con los archivos de lote con Python  ( Problems running batch files with python ) 
Soy bastante nuevo en Python y he estado tratando de ejecutar un archivo .cmd con él, pero no lo ejecutará desde la ubicación correcta. Mi archivo run_setup.c...

1  Python Windows Cmd MKLink, deja de trabajar sin mensaje de error  ( Python windows cmd mklink stops working without error message ) 
Quiero crear enlaces simbólicos para cada archivo en una estructura de directorio anidado, donde todos los enlaces simbólicos se colocarán en una carpeta plan...

0  C popen () cambia la cadena  ( C popen changes the string ) 
Estoy usando popen() para ejecutar un comando de shell en mi máquina Ubuntu (16.04 LTS) y por alguna razón, 9988777668 cambia la cadena de comandos y lueg...

13  Cómo prevenir los bloques de los cgos cuando el flujo de archivos no tiene datos nuevos  ( How to prevent fgets blocks when file stream has no new data ) 
Tengo una función popen() que ejecuta tail -f sometextfile . ASLONG, ya que hay datos en el Filtream, obviamente, puedo obtener los datos a través de fget...

60  Matando un proceso creado con el subproceso de Python.POPEN () [DUPLICADO]  ( Killing a process created with pythons subprocess popen ) 
Esta pregunta ya tiene respuestas aquí : Cómo terminar un subproceso de Python lanzado con Shell = T...

5  Ejecute los comandos de Windows CMD a través de Python  ( Run windows cmd commands via python ) 
Quiero crear una carpeta con SymLinks a todos los archivos en una estructura de gran directorios. Usé subprocess.call(["cmd", "/C", "mklink", linkname, filen...

47  ¿Cómo obtengo información "en tiempo real" de un subproceso.Popen en Python (2.5)  ( How do i get real time information back from a subprocess popen in python 2 5 ) 
Me gustaría usar el módulo de subproceso de la siguiente manera: Crea un nuevo proceso que lo lleva mucho tiempo para ejecutar. Capture stdout (o stde...

0  ¿Cuál es el problema con la ejecución de comandos en Windows Cmd de Python?  ( Whats the problem with executing commands in windows cmd from python ) 
Estoy teniendo enormes problemas con los comandos que pasan a CMD de Python. Primero, abro un proceso CMD: cmdprocess = subprocess.Popen("cmd", ...

3  No se puede ejecutar POPEN.COMMUNICAMIENTO () dos veces. (Módulo de subproceso de Python)  ( Cant run popen communicate twice python subprocess module ) 
¿Puede alguien explicar por qué recibo este error si ejecuto la función de comunicación dos veces? por ejemplo from subprocess import * SVN=Popen('which ...

1  Prueba si un proceso de POMEN está esperando la entrada  ( Test if a popen process is waiting for input ) 
Comienzo un proceso con Popen y en circunstancias normales, debería hacer un trabajo y escribir cosas para STDOUT, que luego capturé. En casos excepcionales, ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos