python 進程互斥鎖Lock(43)

目錄

一.線程互斥鎖和進程互斥鎖注意事項

1.創建線程互斥鎖

2.創建進程互斥鎖

二.進程互斥鎖Lock函數介紹

三.進程互斥鎖Lock使用

案例一:使用進程,但不使用互斥鎖

案例二:進程互斥鎖的使用

案例三:對全局變量累計求和看看計算結果

 

 


和前面講到的  python線程互斥鎖Lock 類似,當有多個進程Process同時讀寫同一個文件時,爲了避免數據讀寫產生異常,我們需要爲正在操作的進程加上互斥鎖,互斥鎖的原理不管是對線程threading還是對進程Process而言都是一樣。

 

一.線程互斥鎖和進程互斥鎖注意事項

1.創建線程互斥鎖

# 導入線程threading模塊
import threading

# 創建線程互斥鎖
mutex = threading.Lock()

 

2.創建進程互斥鎖

from multip# 導入進程模塊
from multiprocessing import Process,Lock

# 創建進程互斥鎖
mutex = Lock()

注意導入模塊的區別,不要混淆使用!

 

二.進程互斥鎖Lock函數介紹

acquire()— 鎖定資源;

release() — 釋放資源;

 

三.進程互斥鎖Lock使用

案例一:使用進程,但不使用互斥鎖

from multiprocessing import Lock, Process
import time
import random
import os


def foo(i, mutex):
    print('%s: %s is running' % (i, os.getpid()))
    time.sleep(random.random())
    print('%s:%s is done' % (i, os.getpid()))


if __name__ == '__main__':
    mutex = Lock()
    for i in range(10):
        process = Process(target=foo, args=(i, mutex))
        process.start()

輸出結果:

0: 17008 is running
1: 5288 is running
2: 1228 is running
3: 9724 is running
4: 7520 is running
5: 10236 is running
3:9724 is done
6: 16452 is running
7: 13328 is running
0:17008 is done
8: 9356 is running
9: 16432 is running
8:9356 is done
2:1228 is done
5:10236 is done
9:16432 is done
7:13328 is done
4:7520 is done
6:16452 is done
1:5288 is done

重輸出的結果來看,多個進程同時在操作,如果是對同一個文件讀寫操作,很明顯已經亂套了,這並不是我們想要的;如果多進程在讀寫同一文件時想要保證數據安全,必然需要加上互斥鎖,例如下面這個demo;

 

案例二:進程互斥鎖的使用

from multiprocessing import Lock, Process
import time
import random
import os


def foo(i, mutex):
    mutex.acquire()
    print('%s: %s is running' % (i, os.getpid()))
    time.sleep(random.random())
    print('%s:%s is done' % (i, os.getpid()))
    mutex.release()


if __name__ == '__main__':
    mutex = Lock()
    for i in range(10):
        process = Process(target=foo, args=(i, mutex))
        process.start()

輸出結果:

0: 6908 is running
0:6908 is done
1: 7976 is running
1:7976 is done
3: 7824 is running
3:7824 is done
2: 17328 is running
2:17328 is done
4: 7844 is running
4:7844 is done
5: 15900 is running
5:15900 is done
6: 12648 is running
6:12648 is done
7: 16516 is running
7:16516 is done
8: 17348 is running
8:17348 is done
9: 13180 is running
9:13180 is done

完美,即便是對同一個文件進行讀寫操作,進程Process使用互斥鎖Lock之後也不會造成數據混亂的問題,同時也提高了效率,完美解決案例一的問題!

 

案例三:對全局變量累計求和看看計算結果

# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解憂
@Blog(個人博客地址): shuopython.com
@WeChat Official Account(微信公衆號):猿說python
@Github:www.github.com

@File:python_process_lock.py
@Time:2019/12/31 21:25

@Motto:不積跬步無以至千里,不積小流無以成江海,程序人生的精彩需要堅持不懈地積累!
"""

# 導入進程模塊
from multiprocessing import Process,Lock

num = 0

def get_sum1():

    global num  # 聲明全局變量
    for i in range(10000):
        num = num +1
    print("get_sum1:",num)

def get_sum2():

    global num  # 聲明全局變量
    for i in range(10000):
        num = num + 1
    print("get_sum2:", num)


def main():
    global num  # 聲明全局變量
    p1 = Process(target=get_sum1)
    p1.start()

    p2 = Process(target=get_sum2)
    p2.start()

    p1.join()
    p2.join()
    print("main:",num)


if __name__ == "__main__":

    main()
    print("main exit")

輸出結果:

get_sum1: 10000
get_sum2: 10000
main: 0
main exit

可能有小夥伴會覺得很納悶,main函數中得num值怎麼會是0,明明主進程/兩個子進程都用關鍵字 global 聲明瞭全局變量,即便沒有互斥鎖,也應該是一個小於20000的隨機數,在文章 python 進程Process與線程threading區別 中有詳細講解,同一進程的所有線程共享該進程的所有資源,進程與進程之間資源相互獨立,互不影響(類似深拷貝)

上面的程序有三個進程,這就意味着num變量實際上有三份資源,其中兩個進程對num分別做了10000次累計加1,所以每個子進程的值都是10000,主進程沒有對num任何操作,所以主進程num值爲0;

 

猜你喜歡:

1.python線程的創建threading.Thread

2.python線程互斥鎖

3.python進程Process

4.python進程Process與線程threading的區別

 

轉載請註明猿說Python » python 進程互斥鎖Lock

 

                                                                    技術交流、商務合作請直接聯繫博主

                                                                               掃碼或搜索:猿說python

python教程公衆號

                                                                                    猿說python

                                                                              微信公衆號 掃一掃關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章