Вы также получите эту ошибку, если в системе есть устаревшие процессы EXCEL.EXE
(используйте [вкладку Task Manager --> Processes
».)
Убейте все эти экземпляры, и приложение будет работать нормально.
Вам необходимо передать дескриптор файла (его можно получить, вызвав метод fileno () объекта file). Код ниже выдает IOError, когда тот же код выполняется в отдельном интерпретаторе.
>>> import fcntl
>>> thefile = open('/tmp/testfile')
>>> fd = thefile.fileno()
>>> fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
Вы можете обратиться к этой публикации для более подробной информации о различных схемах блокировки.
Что касается вашего второго вопроса, используйте 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')