Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / 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 " P2 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 " lauch 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 " P1 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中。 注:我们通过文件锁,解决了进程之间互斥操作同一个资源的问题。如果是同一个线程之间互斥操作同一个资源的问题,我们只需要定义个全局变量即可,我们没有必要使用文件锁,因为文件锁需要访问磁盘。