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

10-09 20:18