python - Portalocker 未按预期退出,而 fcntl 则退出

标签 python python-3.x locking try-catch fcntl

我不明白为什么 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/

相关文章:

python - 如何优化groupby上的apply调用

python - 如何在不关注 pyqt5 python 的情况下显示工具提示?

MySQL 执行 "No impact"临时 INSERT 并避免复制锁定

python - 如何在Python中找出给定日期的周数?

python - PIL - 对每个像素应用相同的操作

python - 在python中滚动数组

python-3.x - pubnub python 4 SDK

windows - 记事本打败了所有人?

c# - 为什么在同一 (UI) 线程中顺序调用 AsyncLock 的方式与不同线程的方式不同(例如通过 Task.Run)?

python - 在 python 中使用 csv 创建字典的问题