Python fcntl не блокируется, как ожидалось

Вы также получите эту ошибку, если в системе есть устаревшие процессы EXCEL.EXE (используйте [вкладку Task Manager --> Processes ».)

Убейте все эти экземпляры, и приложение будет работать нормально.

23
задан ifischer 28 March 2012 в 12:56
поделиться

2 ответа

Вам необходимо передать дескриптор файла (его можно получить, вызвав метод fileno () объекта file). Код ниже выдает IOError, когда тот же код выполняется в отдельном интерпретаторе.

>>> import fcntl
>>> thefile = open('/tmp/testfile')
>>> fd = thefile.fileno()
>>> fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
0
ответ дан Vatine 28 March 2012 в 12:56
поделиться

Вы можете обратиться к этой публикации для более подробной информации о различных схемах блокировки.
Что касается вашего второго вопроса, используйте fcntl для блокировки других процессов (вместо этого используйте lockf для простоты). В Linux lockf это просто оболочка для fcntl, оба связаны с парой (pid, inode).
1. используйте fcntl.fcntl для обеспечения блокировки файлов между процессами.

import os
import sys
import time
import fcntl
import struct


fd = open('/etc/mtab', 'r')
ppid = os.getpid()
print('parent pid: %d' % ppid)
lockdata = struct.pack('hhllh', fcntl.F_RDLCK, 0, 0, 0, ppid)
res = fcntl.fcntl(fd.fileno(), fcntl.F_SETLK, lockdata)
print('put read lock in parent process: %s' % str(struct.unpack('hhllh', res)))
if os.fork():
    os.wait()
    lockdata = struct.pack('hhllh', fcntl.F_UNLCK, 0, 0, 0, ppid)
    res = fcntl.fcntl(fd.fileno(), fcntl.F_SETLK, lockdata)
    print('release lock: %s' % str(struct.unpack('hhllh', res)))
else:
    cpid = os.getpid()
    print('child pid: %d' % cpid)
    lockdata = struct.pack('hhllh', fcntl.F_WRLCK, 0, 0, 0, cpid)
    try:
        fcntl.fcntl(fd.fileno(), fcntl.F_SETLK, lockdata)
    except OSError:
        res = fcntl.fcntl(fd.fileno(), fcntl.F_GETLK, lockdata)
        print('fail to get lock: %s' % str(struct.unpack('hhllh', res)))
    else:
        print('succeeded in getting lock')

2. используйте fcntl.lockf.

import os
import time
import fcntl

fd = open('/etc/mtab', 'w')
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
if os.fork():
    os.wait()
    fcntl.lockf(fd, fcntl.LOCK_UN)
else:
    try:
        fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError as e:
        print('failed to get lock')
    else:
        print('succeeded in getting lock')
0
ответ дан lyu.l 28 March 2012 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: