Portalocker不会按预期退出,而fcntl会退出

时间:2019-04-26 09:07:28

标签: 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

1 个答案:

答案 0 :(得分:1)

异常 是一个优美的示例:import matplotlib.pyplot as plt import numpy as np time_step = np.arange(0, 200.01, 40).tolist() drag3 = [1, 1, 1, 1, 1, 1] lift3 = [1.5, 1, 1, 1, 1, 0.2] second_drag3 = [1.2, 1.2, 1.2, 1.3, 1.2, 0.5] second_lift3 = [1.2, 1.2, 1.2, 1.3, 1.2, 0.8] fig, ax1 = plt.subplots() ax1.plot(time_step, drag3, label="40$C_D1$", color='blue', linestyle='-', linewidth=1.0) ax1.plot(time_step, second_drag3, label="40$C_D2$", color='darkviolet', linestyle='-', linewidth=1.0) ax2 = ax1.twinx() ax2.plot(time_step, lift3, label="40$C_L1$", color='red', linestyle='-', linewidth=1.0) ax2.plot(time_step, second_lift3, label="40$C_L2$", color='limegreen', linestyle='-', linewidth=1.0) plt.tight_layout() fig.legend(loc='lower right', ncol=2, borderaxespad=3) plt.show()

与直接使用portalocker.exceptions.LockException相比,fcntl包装了异常,因此可以在多个平台上使用。 portalocker示例在Windows上不起作用,fcntl可以:)

测试显示了一些有用的示例:https://github.com/WoLpH/portalocker/blob/develop/portalocker_tests/tests.py

就您而言,应该捕获portalocker而不是捕获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)