Procesos de Python, multiprocesos, subprocesos y sincronización y puntos muertos

Una deficiencia de la programación tradicional

Desventajas de la programación tradicional:

# 必须按照顺序执行,多个任务无法同时在还行
import time


def sing():
    for i in range(5):
        print("sing: hero")
        time.sleep(1)       # 每唱一次,等1秒再唱


def dance():
    for i in range(5):
        print("dance: swan")
        time.sleep(1)       # 每唱一次,等1秒再跳


def main():
    sing()
    dance()


if __name__ == "__main__":
    main()

El tiempo dedicado a las dos tareas es de 10 segundos, si quieres bailar y cantar al mismo tiempo, de hecho, las dos tareas se pueden completar cuando se completa la tarea más larga.

Hay muchas formas de implementar la programación multitarea, como: multiproceso, multiproceso, corrutina, etc.

2. Utilice el método multiproceso para lograr múltiples tareas.

# 必须按照顺序执行,多个任务无法同时在还行
import time
import multiprocessing


def sing():
    for i in range(5):
        print("sing: hero")
        time.sleep(1)       # 每唱一次,等1秒再唱


def dance():
    for i in range(5):
        print("dance: swan")
        time.sleep(1)       # 每唱一次,等1秒再跳


def main():
    p1 = multiprocessing.Process(target=sing)
    p2 = multiprocessing.Process(target=dance)
    p1.start()
    p2.start()


if __name__ == "__main__":
    main()

Algunas operaciones de los tres procesos.

htopSe puede ver una lista detallada de procesos a través del comando.

Nota: kill -9 pidDespués de matar el proceso principal, el proceso hijo no se matará. En este momento, la línea de comando no podrá salir normalmente porque la señal de este comando se envía al proceso principal para realizar la tarea de matar. El proceso no tiene un proceso padre. , se convirtió en un proceso huérfano y luego fue adoptado por el proceso init. Es decir, después de finalizar el proceso principal, el proceso padre del proceso hijo se denomina proceso de inicio.

A través de , os.getpid()puede obtener el pid del proceso actual y os.getppid()la identificación del proceso principal.

Cuatro comunicaciones entre procesos.

Los procesos no pueden comunicarse directamente entre sí porque son aplicaciones independientes.

Para lograr la comunicación entre procesos, los métodos comunes incluyen: socket, etc. En Python, puede usar el método de cola para lograr:

queue = multiprocessing.Queue(3)
queue.put("111")
queue.put(222)

# 取数据
res = queue.get()
print(res)
# 判断: q.full()  q.empty()

Grupo de cinco procesos

p = multiprocessing.Pool(3)

Seis métodos de subprocesos múltiples para lograr múltiples tareas

import time
import threading


def sing():
    for i in range(5):
        print("sing: hero")
        time.sleep(1)       # 每唱一次,等1秒再唱


def dance():
    for i in range(5):
        print("dance: swan")
        time.sleep(1)       # 每唱一次,等1秒再跳


def main():
    t1 = threading.Thread(target=sing)      # 创建一个线程对象
    t2 = threading.Thread(target=dance)     # 创建一个线程对象
    t1.start()                              # 开启线程
    t2.start()                              # 开启线程


if __name__ == "__main__":
    main()

API relacionada con siete subprocesos

threading.Thread() Se pueden crear hilos y threading.enumerate()se pueden ver todos los hilos actuales:

import time
import threading


def sing():
    for i in range(5):
        print("sing: hero")
        time.sleep(1)       # 每唱一次,等1秒再唱


def dance():
    for i in range(5):
        print("dance: swan")
        time.sleep(1)       # 每唱一次,等1秒再跳


def main():

    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)

    t1.start()
    t2.start()

    while True:
        length = len(threading.enumerate())
        print("当前线程数为:%d" % length)
        if length <= 1:
            break
        time.sleep(0.5)


if __name__ == "__main__":
    main()

8. Sincronización y punto muerto

Los hilos comparten variables globales, lo que provocará confusión en los datos:

import time
import threading

# 定义共享的全局变量
num = 0


def add100():
    global num
    for i in range(100000):
        num = num + 0.00001


def add1000():
    global num
    for i in range(100000):
        num = num + 1000


def main():

    t1 = threading.Thread(target=add100)
    t2 = threading.Thread(target=add1000)

    t1.start()
    t2.start()

    time.sleep(5)
    print(num)              # 每次输出的结果是不相同的


if __name__ == "__main__":
    main()

Solución para utilizar bloqueos mutex para lograr la sincronización:

import time
import threading

# 定义共享的全局变量
num = 0


def add100():
    global num
    mutex.acquire()     # 加锁:若已经加锁,则会直到锁被揭开
    for i in range(100000):
        num = num + 0.00001
    mutex.release()     # 解锁


def add1000():
    global num
    mutex.acquire()     # 加锁:若已经加锁,则会直到锁被揭开
    for i in range(100000):
        num = num + 1000
    mutex.release()     # 解锁


# 创建互斥锁,默认不会上锁
mutex = threading.Lock()


def main():

    t1 = threading.Thread(target=add100)
    t2 = threading.Thread(target=add1000)

    t1.start()
    t2.start()

    time.sleep(5)
    print(num)          # 100000001.0 永远不会变


if __name__ == "__main__":
    main()

Supongo que te gusta

Origin blog.csdn.net/weixin_51390582/article/details/135549585
Recomendado
Clasificación