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.
htop
Se puede ver una lista detallada de procesos a través del comando.
Nota: kill -9 pid
Despué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()