歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 文件鎖和Python多進程的使用

文件鎖和Python多進程的使用

日期:2017/3/1 10:11:43   编辑:Linux編程

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. def read_file(filename):
  4. all_the_text = ''
  5. fo = open(filename)
  6. try:
  7. all_the_text = fo.read()
  8. finally:
  9. fo.close()
  10. return all_the_text
  11. #根據文件名和內容,寫入文件。成功返回1
  12. def write_file(filename, filecontent):
  13. status = 0
  14. try:
  15. fo = open(filename, 'wb+')
  16. fo.write(filecontent)
  17. status = 1
  18. finally:
  19. fo.close()
  20. 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. #定義線程T2的執行函數
  6. def f2():
  7. fs = read_file('fs.txt')
  8. print '\nP2 want to visit,now fs:',fs
  9. if '22' == fs: #f1操作完file1,f2可以開始操作了
  10. write_file('fs.txt','33') #表明f2正在操作file1
  11. print 'P2 is visiting file1...'
  12. write_file('fs.txt','00')
  13. sleep(10)
  14. else:
  15. sleep(1)
  16. #定義線程T2
  17. def T2():
  18. while True:
  19. f2()
  20. def main():
  21. print '\nlauch process:P2...'
  22. #啟動線程T2
  23. Thread(target = T2,args=()).start()
  24. while True:
  25. sleep(3)
  26. if __name__ == '__main__':
  27. 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. #線程T1的執行函數
  7. def f1():
  8. fs = read_file('fs.txt')
  9. print '\nP1 want to visit,now fs:',fs
  10. assert('00' == fs)
  11. if '00' == fs: #f2操作完file1,f1可以開始操作了
  12. write_file('fs.txt','11') #表明f1正在操作file1
  13. print 'P1 is visiting file1...'
  14. write_file('fs.txt','22')
  15. sleep(10)
  16. else:
  17. sleep(1)
  18. #線程T1
  19. def T1():
  20. while True:
  21. f1()
  22. if __name__ == '__main__':
  23. print 'lauch process:P1...'
  24. #初始化'fs.txt'
  25. write_file('fs.txt','00')
  26. #進程P2的定義
  27. from Process2 import main as P2_main
  28. P2 = Process(target = P2_main, args=())
  29. P2.start()
  30. #啟動線程T1
  31. Thread(target = T1,args=()).start()
  32. while True:
  33. 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