歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

文件鎖和Python多進程的使用

1.文件鎖

問題:進程P1中有一個線程T1,T1執行的函數為f1;進程P2中有一個線程T2,T2執行的函數為f2。

當f1和f2都需要對同一個資源進行操作時,比如同時對文件file1進行操作。為了線程安全,則當f1在操作(讀或寫文件file1)時,不允許f2操作(讀或寫文件file1)。反之,當f2在操作file1時,不允許f1操作file1。即f1和f2不能同時操作file1。

解決方法

可以采用文件鎖(這裡文件鎖的意思為將對資源file1的訪問狀態保存在文件fs.txt裡,即通過文件fs.txt來加鎖)的方式,對文件file1輪流交替的操作:即f1操作完file1之後,f2開始操作file1;當f2操作完file1之後,f1開始操作file1,這樣交替下去。

可以設置4種狀態:00、11、22、33。將這4種狀態保存在文件‘fs.txt’裡,因為這樣進程P1和P2都可以操作文件fs.txt(解決了進程間相互通信的問題)。4種狀態分別表示如下:

00:表示f1可以操作資源file1了,同時也表示f2操作完畢file1;

11:表示f1正在操作資源file1;

22:表示f1操作完畢file1,同時也表示f2可以操作file1了;

33:表示f2正在操作file1。

訪問流程圖如下所示:


我們可以看到,函數f1的狀態順序為'00' ->'11' -> '22';函數f2的狀態順序為'22' -> '33' -> '00'。

形成了如下的環形交替訪問:


2.Python中多進程的使用

下面將python中多進程的使用和文件鎖進行結合,給出一個簡單的demo。

公共函數(讀文件、寫文件)定義在文件GlobalFunc.py中:

  1. # encoding: utf-8   
  2.   
  3. #根據文件名,讀取文件內容   
  4. def read_file(filename):  
  5.     all_the_text = ''  
  6.     fo = open(filename)  
  7.     try:  
  8.         all_the_text = fo.read()  
  9.     finally:  
  10.         fo.close()  
  11.     return all_the_text  
  12.       
  13.   
  14. #根據文件名和內容,寫入文件。成功返回1   
  15. def write_file(filename, filecontent):  
  16.     status = 0  
  17.     try:  
  18.         fo = open(filename, 'wb+')  
  19.         fo.write(filecontent)  
  20.         status = 1  
  21.     finally:  
  22.         fo.close()  
  23.     return status  
進程P2的文件Process2.py定義如下:
  1. # encoding: utf-8   
  2. from threading import Thread  
  3. from time import sleep  
  4. from GlobalFunc import read_file,write_file  
  5.   
  6. #定義線程T2的執行函數   
  7. def f2():  
  8.     fs = read_file('fs.txt')  
  9.     print '\nP2 want to visit,now fs:',fs  
  10.     if '22' == fs:  #f1操作完file1,f2可以開始操作了   
  11.         write_file('fs.txt','33'#表明f2正在操作file1   
  12.   
  13.         print 'P2 is visiting file1...'  
  14.   
  15.         write_file('fs.txt','00')  
  16.         sleep(10)  
  17.     else:  
  18.         sleep(1)  
  19.   
  20. #定義線程T2   
  21. def T2():  
  22.     while True:  
  23.         f2()  
  24.   
  25. def main():  
  26.     print '\nlauch process:P2...'  
  27.     #啟動線程T2   
  28.     Thread(target = T2,args=()).start()  
  29.     while True:  
  30.         sleep(3)  
  31.       
  32. if __name__ == '__main__':  
  33.     main()  
進程P1的文件Process.py定義如下:
  1. # encoding: utf-8   
  2. from threading import Thread  
  3. from time import sleep  
  4. from multiprocessing import Process  
  5. from GlobalFunc import read_file,write_file  
  6.   
  7. #線程T1的執行函數   
  8. def f1():  
  9.     fs = read_file('fs.txt')  
  10.     print '\nP1 want to visit,now fs:',fs  
  11.     assert('00' == fs)  
  12.     if '00' == fs:  #f2操作完file1,f1可以開始操作了   
  13.         write_file('fs.txt','11'#表明f1正在操作file1   
  14.   
  15.         print 'P1 is visiting file1...'  
  16.   
  17.         write_file('fs.txt','22')  
  18.         sleep(10)  
  19.     else:  
  20.         sleep(1)  
  21.   
  22. #線程T1   
  23. def T1():  
  24.     while True:  
  25.         f1()  
  26.   
  27. if __name__ == '__main__':  
  28.     print 'lauch process:P1...'  
  29.     #初始化'fs.txt'   
  30.     write_file('fs.txt','00')  
  31.   
  32.     #進程P2的定義   
  33.     from Process2 import main as P2_main  
  34.     P2 = Process(target = P2_main, args=())  
  35.     P2.start()  
  36.       
  37.     #啟動線程T1   
  38.     Thread(target = T1,args=()).start()  
  39.       
  40.     while True:  
  41.         sleep(3)  
進程P2單獨定義成一個文件'Process2.py'。通過進程P1來調用啟動進程P2,進程P1中有一個線程T1,進程P2中有一個線程T2,T1和T2都對文件file1進行操作。我們通過'fs.txt'這個文件設置文件鎖,將T1和T2的當前操作狀態保存在fs.txt中。

注:我們通過文件鎖,解決了進程之間互斥操作同一個資源的問題。如果是同一個線程之間互斥操作同一個資源的問題,我們只需要定義個全局變量即可,我們沒有必要使用文件鎖,因為文件鎖需要訪問磁盤。

Copyright © Linux教程網 All Rights Reserved