Red de conocimiento informático - Problemas con los teléfonos móviles - Cómo implementar un proceso en Python

Cómo implementar un proceso en Python

Para aprovechar al máximo los recursos de la CPU de múltiples núcleos, en la mayoría de los casos es necesario utilizar múltiples procesos en Python. Python proporciona el paquete de multiprocesamiento para implementar múltiples procesos. El multiprocesamiento admite la sincronización y la comunicación entre procesos secundarios y procesos, y proporciona componentes como proceso, cola, canalización y bloqueo.

Abrir un proceso hijo

El multiprocesamiento proporciona la clase Proceso para generar instancias de proceso

Proceso([grupo [, destino [, nombre [, args [, kwargs] ]]]]])1

La agrupación de grupos no se utiliza realmente

el objetivo representa el objeto que llama. Puede pasar el nombre del método

args. representa el El objeto que llama proporciona parámetros en forma de tuplas. Por ejemplo, el objetivo es la función a y tiene dos parámetros m, n. Entonces los parámetros son args=(m, n)

kwargs. el nombre del Diccionario del objeto que llama es un alias, lo que equivale a darle un nombre a este proceso.

Primero tomemos un pequeño ejemplo: # -*- codificación:utf-8 -* -desde el proceso de importación multiprocesamiento, Poolimport osimport timedef run_proc(wTime):

n = 0

while n < 3: print "subProcess %s run", % os.getpid() , "{0}" .format(time.ctime()) #Obtener el número de proceso actual y el tiempo de ejecución

time.sleep(wTime) #Esperar (dormir)

n += 1if __name__ == "__main__":

p = Proceso(target=run_proc, args=(2,)) ?#Aplicar para proceso hijo

p.start() #Ejecutar proceso

print "Proceso principal en ejecución. El subProceso es ", p.pid print "Fin del proceso principal,{0}".format(time.ctime())12345678910111213141516171819

Resultados de la ejecución:

¿El proceso principal se ejecuta? Lun 27 de marzo 11: 20:21 2017?

SubProceso 30196 ejecutado, Lun 27 de marzo 11:20:23 2017?

SubProceso 30196 ejecutado, Lun 27 de marzo 11:20:25 2017

Según los resultados de la ejecución, se puede ver que el proceso hijo todavía se está ejecutando después de que finaliza el proceso padre, lo que puede provocar un proceso zombie.

Normalmente, cuando el proceso hijo finaliza, notificará al proceso padre, borrará la memoria que ocupa y dejará su propia información de salida en el kernel. Cuando el proceso padre se entera de que el proceso hijo ha terminado, recuperará la información de salida del proceso hijo del kernel. Sin embargo, si el proceso padre termina antes que el proceso hijo, esto puede hacer que la información de salida del proceso hijo permanezca en el kernel y el proceso hijo se convierta en un proceso zombie. Cuando se acumula una gran cantidad de procesos zombies, se ocupará espacio en la memoria.

¿Hay alguna forma de evitar procesos zombies? ?

Aquí introducimos un atributo del proceso, deamon. Cuando su valor es VERDADERO, su proceso padre finaliza y el proceso también finaliza directamente (incluso si no ha terminado de ejecutarse). ?

Así que agregue p.deamon = true al programa anterior y vea el efecto. # -*- codificación:utf-8 -*-desde proceso de importación multiprocesamiento, Poolimport osimport timedef run_proc(wTime):

n = 0

while n < 3: print "subProcess %s ejecutar", % os.getpid(), "{0}".format(time.ctime())

time.sleep(wTime)

n += 1if __name__ == "__main__":

p = Proceso(target=run_proc, args=(2,))

p.daemon = True #Agregar demonio

p.start() print "Proceso principal en ejecución. El subProceso es ", p.pid print "Fin del proceso principal,{0}".format(time.ctime())1234567891011121314151617181920

Resultado de la ejecución:

¿El proceso principal se está ejecutando. El subproceso es 31856?

Fin del proceso principal, lunes 27 de marzo 11:40:10 2017

Este es el problema nuevamente, el subproceso tiene no se ha ejecutado, lo cual no es el resultado esperado.

¿Hay alguna forma de finalizar el proceso principal una vez que el proceso secundario haya terminado de ejecutarse? ?

Aquí se presenta el método p.join(), que hace que el proceso principal ejecute el código posterior después de que finaliza la ejecución del proceso secundario # -*- coding:utf-8 -*-. del proceso de importación multiprocesamiento, Poolimport osimport timedef run_proc(wTime):

n = 0

while n < 3: print "subProcess %s run", % os.getpid(), "{0}". formato(time.ctime())

time.sleep(wTime)

n += 1if __name__ == "__main__":

p = Proceso( target=run_proc, args=(2,))

p.daemon = True

p.start()

p. join() #Método de unión

print "Proceso principal en ejecución. El subproceso es ", p.pid print "Fin del proceso principal,{0}".format(time.ctime())123456789101112131415161718192021

Resultado de la ejecución:

¿ejecución del subproceso 32076, lunes 27 de marzo a las 11:46:07 de 2017?

ejecución del subproceso 32076, lunes 27 de marzo a las 11:46:09 de 2017?

p>

¿Se ejecuta el subproceso 32076, lunes 27 de marzo 11:46:11 de 2017?

¿Se ejecuta el proceso principal? ¿El subproceso es 32076?

Fin del proceso principal, lunes 27 de marzo 11: 46:13 2017

De esta manera, todos los procesos se pueden ejecutar sin problemas.

Definir procesos en clases

Al heredar la clase Proceso, puede personalizar la clase de proceso e implementar el método de ejecución. La instancia p llama automáticamente al método de ejecución cuando se llama a p.start().

?

Como sigue: # -*- coding:utf-8 -*-from proceso de importación multiprocesamiento, Poolimport osimport timeclass Myprocess(Process):

def __init__(self, wTime) :

Process.__init__(self)

self.wTime = wTime def run(self):

n = 0

mientras n < 3: imprimir "subProceso %s ejecución", % os.getpid(), "{0}".format(time.ctime())

time.sleep(self.wTime)

n += 1if __name__ == "__main__":

p = Miproceso(2)

p.daemon = True

p. start () #Llamar automáticamente al método de ejecución

p.join() print "Proceso principal en ejecución. El subproceso es ", p.pid print "Fin del proceso principal,{0}".format(time.ctime () )12345678910111213141516171819202122232425262728

El resultado de la ejecución es el mismo que en el ejemplo anterior.

Crear múltiples procesos

Muchas veces el sistema necesita crear múltiples procesos para mejorar la utilización de la CPU. Cuando el número es pequeño, puede generar manualmente instancias de proceso una por una. Cuando hay una gran cantidad de procesos, es posible utilizar bucles, pero esto requiere que los programadores administren manualmente la cantidad de procesos concurrentes en el sistema, lo que a veces es problemático. En este momento, el grupo de procesos Pool puede desempeñar su función. Puede limitar la cantidad de procesos simultáneos pasando parámetros. El valor predeterminado es la cantidad de núcleos de la CPU.

?

Vaya directamente al ejemplo: # -*- coding:utf-8 -*-from multiprocesamiento import Process, Poolimport os, timedef run_proc(name): ##Defina una función para llamar al proceso

para i en rango(5):

time.sleep(0.2) #Dormir durante 0.2 segundos

print 'Ejecutar proceso hijo %s (%s)' % (name, os.getpid())#Se tarda 1 segundo en ejecutar esta función una vez si __name__ =='__main__': #Ejecutar el proceso principal

print 'Ejecutar el proceso principal (%s) .' % (os.getpid())

mainStart = time.time() #Registrar la hora en que se inicia el proceso principal

p = Pool(8) #¿Abrir un? grupo de procesos

para i en rango(16): #Abrir 14 procesos

p.apply_async(run_proc,args=('Proceso'+str(i),))#Each proceso Se llama a la función run_proc

#args representa los parámetros pasados ​​a la función.

print 'Esperando que todos los subprocesos hayan finalizado...'

p.close() #Cerrar el grupo de procesos

p.join() ?#Esperando para abrir Después de que se hayan ejecutado todos los procesos, el proceso principal continuará ejecutándose

print 'Todos los subprocesos completados'

mainEnd = time.time() ?#Registrar la hora de finalización del proceso principal

p>

print 'Todo el proceso ejecutó %0.2f segundos.' % (mainEnd-mainStart)?#Tiempo de ejecución del proceso principal 123456789101112131415161718192021222324

Resultado de la ejecución: ?

Parte inicial

Ejecutar el proceso principal (30920).?

¿Esperando que se completen todos los subprocesos...?

Ejecutar el proceso secundario. ¿Proceso0 (32396)?

¿Ejecutar el proceso hijo Proceso3 (25392)?

¿Ejecutar el proceso hijo Proceso1 (28732)?

Ejecutar el proceso hijo Proceso2 (32436)

Última parte:

p>

¿Ejecutar el proceso hijo Process15 (25880)?

¿Todos los subprocesos terminados?

Todos los procesos al final 2,49 segundos.

Instrucciones relacionadas:

El límite de la cantidad de procesos concurrentes en el grupo de procesos aquí es 8, y se generarán 16 procesos cuando el programa se esté ejecutando. El grupo administrará automáticamente la cantidad de procesos simultáneos en el sistema y los procesos restantes esperarán en la cola.

La razón para limitar el número de procesos concurrentes es que cuantos más procesos concurrentes haya en el sistema, mejor. Demasiados procesos concurrentes pueden hacer que la CPU dedique la mayor parte de su tiempo a la programación de procesos en lugar de realizar cálculos efectivos.

Cuando se utiliza tecnología de concurrencia multiproceso, en lo que respecta a un único procesador, su ejecución de procesos es en serie. Sin embargo, es impredecible qué proceso obtendrá recursos de la CPU y se ejecutará en un momento específico (por ejemplo, al comienzo del resultado de la ejecución, el orden de ejecución de cada proceso es incierto), lo que refleja la naturaleza asincrónica del proceso.

Si un solo programa ejecuta la función run_proc 14 veces, tomará al menos 16 segundos. A través de la concurrencia del proceso, solo toma 2,49 segundos, lo que muestra las ventajas de la concurrencia.