Processos Python, multiprocessos, threads e sincronização e impasses

Uma deficiência da programação tradicional

Desvantagens da programação 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()

O tempo gasto nas duas tarefas é de 10 segundos. Se você quiser dançar e cantar ao mesmo tempo, na verdade, as duas tarefas podem ser concluídas quando a tarefa mais longa for concluída.

Existem muitas maneiras de implementar programação multitarefa, como: multiprocesso, multithread, corrotina, etc.

2. Use o método multiprocesso para realizar multitarefa

# 必须按照顺序执行,多个任务无法同时在还行
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()

Algumas operações dos três processos

htopUma lista detalhada de processos pode ser visualizada através do comando.

Nota: kill -9 pidApós encerrar o processo principal, o processo filho não será eliminado. Neste momento, a linha de comando não poderá sair normalmente porque o sinal deste comando é enviado ao processo principal para executar a tarefa de eliminação. O filho process não possui um processo pai. , tornou-se um processo órfão e posteriormente foi adotado pelo processo init. Ou seja, depois de eliminar o processo principal, o processo pai do processo filho é chamado de processo init.

Através de , os.getpid()você pode obter o pid do processo atual e os.getppid()o id do processo pai.

Quatro comunicação entre processos

Os processos não podem se comunicar diretamente entre si porque são aplicativos independentes.

Para conseguir a comunicação entre processos, os métodos comuns incluem: soquete, etc. Em Python, você pode usar o método queue para conseguir:

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

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

Conjunto de cinco processos

p = multiprocessing.Pool(3)

Seis métodos multithreading para realizar multitarefa

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 a sete threads

threading.Thread() Threads podem ser criados e threading.enumerate()todos os threads atuais podem ser visualizados:

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. Sincronização e impasse

Threads compartilham variáveis ​​globais, o que causará confusão nos dados:

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()

Solução para usar bloqueios mutex para obter sincronização:

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()

Acho que você gosta

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