Python プロセス、マルチプロセス、スレッド、同期とデッドロック

従来のプログラミングの欠点

従来のプログラミングの欠点:

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

2 つのタスクに費やす時間は 10 秒です。実際に、踊りと歌を同時にやりたい場合は、最も長いタスクが完了した時点で 2 つのタスクを完了することができます。

マルチプロセス、マルチスレッド、コルーチンなど、マルチタスク プログラミングを実装するにはさまざまな方法があります。

2. マルチプロセス方式でマルチタスクを実現

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

3つのプロセスの一部の操作

詳細なプロセスのリストは、コマンドを通じてhtop表示できます。

注:kill -9 pidメイン プロセスを強制終了した後、子プロセスは強制終了されません。この時点では、このコマンドのシグナルがメイン プロセスに送信されて強制終了タスクを実行するため、コマンド ラインは正常に終了できません。プロセスには親プロセスがありません。 は孤立プロセスとなり、後に init プロセスに採用されました。つまり、メインプロセスを強制終了した後、子プロセスの親プロセスは init プロセスと呼ばれます。

を通じて、os.getpid()現在のプロセスの pid とos.getppid()親プロセスの id を取得できます。

4つのプロセス間通信

プロセスは独立したアプリケーションであるため、プロセス同士は直接通信できません。

プロセス間の通信を実現するための一般的なメソッドには、ソケットなどがあります。Python では、キュー メソッドを使用して以下を実現できます。

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

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

5 つのプロセス プール

p = multiprocessing.Pool(3)

マルチタスクを実現する6つのマルチスレッド方式

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

7つのスレッド関連API

threading.Thread() スレッドを作成しthreading.enumerate()現在のすべてのスレッドを表示できます。

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. 同期とデッドロック

スレッドはグローバル変数を共有するため、データの混乱が生じます。

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

ミューテックス ロックを使用して同期を実現する解決策:

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

おすすめ

転載: blog.csdn.net/weixin_51390582/article/details/135549585