スレッドロックとプロセスロックの概要

3554 ワード

pythonのマルチスレッドとマルチプロセスでは、マルチスレッドまたはマルチプロセスの共有リソースまたはオブジェクトを変更する必要がある場合、cpuのランダムなスケジューリングによって結果が予想と一致しないという問題が発生することがよくあります.
スレッドの例:
from threading import Thread,Lock

x = 0
def task():
    global x
    for i in range(200000):
        x = x+1
'''
  
t1   x   0          
t2   x  0   +1       1
t1         x = 0  +1  1
  :      1?     1              +2    +1
           .
'''        


if __name__ == '__main__':
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    print(x)

479261
from  multiprocessing import Process,Lock
import json,time,os

def search():
    time.sleep(1) #     io
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        print(f'  {res["count"]}')

def get():
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
    time.sleep(1) #     io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db.txt',mode='wt',encoding='utf-8') as f:
            json.dump(res,f)
            print(f'  {os.getpid()}     ')
        time.sleep(1.5) #     io
    else:
        print('      !!!!!!!!!!!')

def task():
    search()
    get()

if __name__ == '__main__':

    for i in range(5):
        p = Process(target=task)
        p.start()

残り1残り1残り1残り1残り1プロセス6292チケット奪取成功プロセス10604チケット奪取成功プロセス19280チケット奪取成功プロセス272チケット奪取成功プロセス12272チケット奪取成功プロセス
この場合、共有オブジェクトを変更すると、ロックを取得したスレッドの操作が実行されるまで、他のスレッドまたはプロセスがこのオブジェクトにアクセスできないことを保証するために、スレッドまたはプロセスをロックする必要があります.したがって、ロックはマルチスレッドとマルチプロセスの同期として機能し、各スレッドとプロセスに必要な操作の完全な実行を保護します.
#   
from threading import Thread,Lock

x = 0
mutex = Lock()
def task():
    global x
    mutex.acquire()
    for i in range(200000):
        x = x+1

    mutex.release()

if __name__ == '__main__':
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    print(x)

600000
from  multiprocessing import Process,Lock
import json,time,os

def search():
    time.sleep(1) #     io
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        print(f'  {res["count"]}')

def get():
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        # print(f'  {res["count"]}')
    time.sleep(1) #     io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db.txt',mode='wt',encoding='utf-8') as f:
            json.dump(res,f)
            print(f'  {os.getpid()}     ')
        time.sleep(1.5) #     io
    else:
        print('      !!!!!!!!!!!')

def task(lock):
    search()

    #   
    lock.acquire()
    get()
    lock.release()
    #     

if __name__ == '__main__':
    lock = Lock() #                   .
    for i in range(15):
        p = Process(target=task,args=(lock,))
        p.start()
        # p.join()

    #                  
    #  join              


#          ,       .

残りは1残りは1残りは1残りは1プロセス16868チケットを夺い取り成功チケットが売り切れました!!!チケットは完売しました!!!チケットは完売しました!!!チケットは完売しました!!!