我不明白为什么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 和 ...一切正常!
#!/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之间的行为存在差异?
附言:蟒蛇 3.6.7乌班图 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)