我不明白为什么Portalocker不会因消息“存在锁文件”而正常失败。而是,它失败并显示以下错误:
portalocker.exceptions.LockException: [Errno 11] Resource temporarily unavailable
请注意,已经有人提出了这个问题,但没有人说服自己。见python-lock-a-file
这是有问题的脚本,必须在两个不同的控制台中启动。
#!/usr/bin/python3
import portalocker
import sys
def open_and_lock(full_filename):
file_handle = open(full_filename, 'w')
try:
portalocker.lock(file_handle, portalocker.LOCK_EX | portalocker.LOCK_NB)
return file_handle
except IOError:
print ("there is a lockfile")
sys.exit(-1)
# positioning a lock
lock_name = 'my_lock'
fh = open_and_lock(lock_name)
# do something consumer in time
i = 0
while (i < 100000000):
i += 1
print ("i :", i)
# lock release
close(fh)
用fcntl替换Portalocker,然后……一切正常!
#!/usr/bin/python3
import fcntl
import sys
def open_and_lock(full_filename):
file_handle = open(full_filename, 'w')
try:
fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
return file_handle
except IOError:
print ("there is a lockfile")
sys.exit(-1)
# positioning a lock
lock_name = 'my_lock'
fh = open_and_lock(lock_name)
# do something consumer in time
i = 0
while (i < 100000000):
i += 1
print ("i :", i)
# lock release
close(fh)
到底是怎么回事 ?为什么Portalocker和fcntl之间的行为存在差异?
ps:
的Python 3.6.7
Ubuntu 18.04
最佳答案
唯一的例外是:portalocker.exceptions.LockException
与直接使用fcntl
相反,portalocker
包装异常,因此它可以在多个平台上工作。 fcntl
示例在Windows上不起作用,portalocker
可以:)
测试显示了一些有用的示例:https://github.com/WoLpH/portalocker/blob/develop/portalocker_tests/tests.py
对于您的情况,应该捕获IOError
而不是捕获portalocker.exceptions.LockException
。另外,您还应该始终正确解锁,因此我建议以下方法:
#!/usr/bin/python3
import portalocker
import sys
# positioning a lock
lock_name = 'my_lock'
try:
with portalocker.Lock(lock_name, portalocker.LOCK_EX | portalocker.LOCK_NB):
# do something consumer in time
i = 0
while (i < 100000000):
i += 1
print ("i :", i)
except portalocker.exceptions.LockException:
print ("there is a lockfile")
sys.exit(-1)
或者,如果您确实要显式锁定和解锁,请执行以下操作:
#!/usr/bin/python3
import portalocker
import sys
def open_and_lock(full_filename):
file_handle = open(full_filename, 'w')
try:
portalocker.lock(file_handle, portalocker.LOCK_EX | portalocker.LOCK_NB)
return file_handle
except portalocker.exceptions.LockException:
print ("there is a lockfile")
sys.exit(-1)
# positioning a lock
lock_name = 'my_lock'
fh = open_and_lock(lock_name)
try:
# do something consumer in time
i = 0
while (i < 100000000):
i += 1
print ("i :", i)
finally:
# lock release
portalocker.unlock(fh)
关于python - Portalocker不会按预期退出,而fcntl会退出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55864281/