我不明白为什么 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
就您而言,您应该捕获portalocker.exceptions.LockException
,而不是捕获IOError
。此外,您也应该始终正确解锁,因此我建议采用以下方法:
#!/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/