Python: ファイルロックによる排他制御(サンプルソース)

2010年2月14日

前回は排他制御について説明しました。


今回は排他制御を体感するためのサンプルソースを紹介します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/python 
# -*- encoding: utf-8 -*- 
# coding: utf-8 
import sys, os, time 
import fcntl as f 
Locked_fn = "./hoge.txt" 
def createLock():
    """
    ロックファイルを生成し、書き込み・スリープを行う。 
    """
    global Locked_fn 
    pid = os.getpid() 
    wfp = file(Locked_fn, "w") 
    t = 10 
    f.flock(wfp.fileno(), f.LOCK_EX) # ファイルロック獲得 
    while ( t > 0 ): 
        wfp.write("writing...\n")
        print "[%d] still lock." % pid 
        time.sleep(1) 
        t -= 1 
        print "[%d] unlock!" % pid 
    f.flock(wfp.fileno(), f.LOCK_UN) # ファイルロック解放 
    wfp.close()

    def getLock(): 
        """ 
        ファイルロックが獲得できるまで、ロック取得・スリープを行う。
        """ 
        global Locked_fn 
        pid = os.getpid() 
        rfp = file(Locked_fn, "r") 
        while ( True ): 
            print "[%d] wait lock." % pid 
            f.flock(rfp.fileno(), f.LOCK_EX) 
            # f.flock(rfp.fileno(), f.LOCK_SH) 
            break 
        print "[%d] get lock!" % pid 
        f.flock(rfp.fileno(), f.LOCK_UN) 
        print "[%d] unlock!" % pid 
        rfp.close() 

def main(): 
    global Locked_fn 
    if not ( os.path.isfile(Locked_fn) ): 
        # ロックを取得するプロセス 
        createLock() 
    else: 
        # ロック待ちになるプロセス 
        getLock() 

if ( __name__ == "__main__" ): 
    main()

これを以下のように複数同時に立ち上げることで、 最初のプロセスがファイル書き込みでファイルオープンし排他ロックを獲得し、 その後他の読み込みプロセスがブロックされる様子を確認できます。

1
$ ./filelock.py &; ./filelock.py &; ./filelock.py&;