python - Portalocker 未按预期退出,而 fcntl 则退出
问题描述
我不明白为什么 portallocker 没有优雅地失败并显示“有一个锁文件”的消息。相反,它失败并出现以下错误:
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/portallocker/blob/develop/portallocker_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)
推荐阅读
- c - 如何在不使用 qsort 的情况下在 C 中实现后缀数组?
- reactjs - TypeError:无法读取未定义的属性“temp”
- laravel - Vue.component() 语句中的路径如何工作?
- python - 如何对由数字列和分类列组成的数据框进行下采样?
- python - scrapy httpcache 不更新缓存
- excel - 如何每天发送一次电子邮件?
- java - Json UTF-8 文件被 Tomcat 错误地检索,但不是 Eclipse
- multithreading - Delphi:如何从 idHTTPServer.OnCommandGet 方法在主线程中执行程序
- java - Java ClassNotFoundException 驱动程序未加载
- c# - 具有多个选项卡的 Razor 页面,这些选项卡预填充了已插入的数据