pythonで書き込み読み込み中のファイルにwriteをぶつけるとファイルが壊れる(?)らしく
pythonだけで排他ロックをかけたい場合
fcntl.flock関数を使う
公式リファレンス
https://docs.python.org/ja/3/library/fcntl.html
ロック獲得に失敗した場合に排出されるエラーが、
2系と3系で違うので注意(たしかIOErrorとOSError)。
下記は2系
#!/usr/bin/python
# -*- coding: utf-8 -*-
import fcntl
import inspect
import time
max_retry_count = 3
pouse_second = 1
try:
with open("/home/foo/bat.txt", 'r') as fileobj:
for i in range(max_retry_count):
try:
# ロック獲得(共有ロック)
fcntl.flock(fileobj.fileno(),
fcntl.LOCK_SH | fcntl.LOCK_NB)
except IOError as ioerror:
"/home/foo/record.log".write('{n}:{f}:{m}'.format(
n=__name__,
f=inspect.currentframe().f_code.co_name,
m=ioerror.args))
if i + 1 == max_retry_count:
raise
# ロック獲得失敗
time.sleep(pouse_second)
continue
try:
# ロック獲得成功
wifi_ap_id = fileobj.read()
break
except Exception as e:
# 異常発生
raise ValueError(e)
finally:
fcntl.flock(fileobj.fileno(), fcntl.LOCK_UN)
except Exception as e:
"/home/foo/record.log".write('{n}:{f}:{m}'.format(
n=__name__,
f=inspect.currentframe().f_code.co_name,
m=e.args))
書き込みは下記の通り
#!/usr/bin/python
# -*- coding: utf-8 -*-
import fcntl
import inspect
import time
max_retry_count = 3
pouse_second = 1
try:
filepath = "/home/foo.kakikomisaki.txt"
jstr = "kakikomitaimoji"
if os.path.isfile(filepath):
option = "r+"
else:
option = "w"
with open(filepath, option) as fileobj:
for i in range(max_retry_count):
try:
# ロック獲得
fcntl.flock(fileobj.fileno(),
fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError as ioerror:
"/home/foo/record.log".write('{n}:{f}:{m}'.format(
n=__name__,
f=inspect.currentframe().f_code.co_name,
m=ioerror.args))
if i + 1 == max_retry_count:
raise
# ロック獲得失敗
time.sleep(pouse_second)
continue
try:
# ロック獲得成功 ボディ部保存
fileobj.truncate()
fileobj.write(jstr)
break
except Exception as e:
# 異常発生
raise ValueError(e)
finally:
fcntl.flock(fileobj.fileno(), fcntl.LOCK_UN)
except Exception as _exception:
"/home/foo/record.log".write('{n}:{f}:{m}'.format(
n=__name__,
f=inspect.currentframe().f_code.co_name,
m=_exception.args))