fcntl.md
1> **Источник:** https://python-all.ru/3.0/library/fcntl.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `fcntl` – системные вызовы `fcntl()` и `ioctl()`89*Платформы:* Unix1011Этот модуль выполняет управление файлами и вводом-выводом для файловых дескрипторов. Он является интерфейсом к Unix-функциям `fcntl` и `ioctl`.1213Все функции этого модуля принимают файловый дескриптор *fd* в качестве первого аргумента. Это может быть целочисленный файловый дескриптор, например, возвращаемый `sys.stdin.fileno()`, или сам файловый объект, например `sys.stdin`, который предоставляет `fileno()`, возвращающую настоящий файловый дескриптор.1415Модуль определяет следующие функции:1617#### `[fcntl.fcntl]fcntl.fcntl(fd, op[, arg])`1819Выполняет запрошенную операцию над файловым дескриптором *fd* (также принимаются файловые объекты, предоставляющие метод `fileno()`). Операция определяется *op* и зависит от операционной системы. Эти коды также находятся в модуле `fcntl`. Аргумент *arg* необязателен и по умолчанию равен целочисленному значению `0`. При наличии он может быть либо целым числом, либо строкой. Если аргумент отсутствует или является целым числом, возвращаемое значение этой функции является целочисленным возвращаемым значением C-вызова `fcntl`. Когда аргумент является строкой, он представляет двоичную структуру, например, созданную с помощью [`struct.pack()`](https://python-all.ru/3.0/library/struct.html#struct.pack). Двоичные данные копируются в буфер, адрес которого передается C-вызову `fcntl`. Возвращаемое значение после успешного вызова – содержимое буфера, преобразованное в строковый объект. Длина возвращаемой строки будет равна длине аргумента *arg*. Это ограничено 1024 байтами. Если информация, возвращаемая операционной системой в буфере, больше 1024 байт, это, скорее всего, приведет к ошибке сегментации или более скрытому повреждению данных.2021Если `fcntl` завершается неудачей, возбуждается исключение [`IOError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IOError).2223#### `[fcntl.ioctl]fcntl.ioctl(fd, op[, arg[, mutate_flag]])`2425Эта функция идентична функции [`fcntl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.fcntl), за исключением того, что обработка аргументов ещё сложнее.2627Параметр op ограничен значениями, которые могут помещаться в 32 бита.2829Параметр *arg* может быть целым числом, отсутствовать (рассматривается так же, как целое число `0`), объектом, поддерживающим интерфейс буфера только для чтения (скорее всего, обычная строка Python), или объектом, поддерживающим интерфейс буфера для чтения и записи.3031Во всех случаях, кроме последнего, поведение такое же, как у функции [`fcntl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.fcntl).3233Если передан изменяемый буфер, то поведение определяется значением параметра *mutate\_flag*.3435Если он ложен, изменяемость буфера игнорируется, и поведение такое же, как для буфера только для чтения, за исключением того, что упомянутое выше ограничение в 1024 байта не действует – до тех пор, пока передаваемый буфер имеет длину не меньше той, которую операционная система хочет туда записать, всё должно работать.3637Если *mutate\_flag* равен true (по умолчанию), то буфер (фактически) передается нижележащему системному вызову [`ioctl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.ioctl), код возврата последнего передается обратно вызывающему Python, а новое содержимое буфера отражает действие [`ioctl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.ioctl). Это небольшое упрощение, потому что если предоставленный буфер имеет длину менее 1024 байт, он сначала копируется в статический буфер длиной 1024 байта, который затем передается [`ioctl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.ioctl) и копируется обратно в предоставленный буфер.3839Пример:4041```python42>>> import array, fcntl, struct, termios, os43>>> os.getpgrp()441334145>>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, " "))[0]461334147>>> buf = array.array('h', [0])48>>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)49050>>> buf51array('h', [13341])52```5354#### `[fcntl.flock]fcntl.flock(fd, op)`5556Выполняет операцию блокировки5758*op*5960над файловым дескриптором6162*fd*6364(также принимаются файловые объекты, предоставляющие метод6566`fileno()`6768). Подробнее см. в Unix-руководстве6970*flock(3)*7172. (В некоторых системах эта функция эмулируется с помощью7374`fcntl`7576.)7778#### `[fcntl.lockf]fcntl.lockf(fd, operation[, length[, start[, whence]]])`7980По сути, это обёртка вокруг вызовов блокировки [`fcntl()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.fcntl). *fd* – это файловый дескриптор файла, который нужно заблокировать или разблокировать, а *operation* – одно из следующих значений:8182- `LOCK_UN` – разблокировать83- `LOCK_SH` – захватить разделяемую блокировку84- `LOCK_EX` – захватить исключительную блокировку8586Когда *operation* равно `LOCK_SH` или `LOCK_EX`, его можно побитово объединить с `LOCK_NB`, чтобы избежать блокировки при получении блокировки. Если используется `LOCK_NB` и блокировку не удаётся получить, будет возбуждено исключение [`IOError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IOError), и у исключения будет атрибут *errno*, установленный в `EACCES` или `EAGAIN` (в зависимости от операционной системы; для переносимости проверяйте оба значения). По крайней мере в некоторых системах `LOCK_EX` можно использовать только если файловый дескриптор ссылается на файл, открытый для записи.8788*length* – это количество блокируемых байтов, *start* – это смещение в байтах, с которого начинается блокировка, относительно *whence*, а *whence* работает как в `fileobj.seek()`, а именно:8990- `0` – относительно начала файла (`SEEK_SET`)91- `1` – относительно текущей позиции в буфере (`SEEK_CUR`)92- `2` – относительно конца файла (`SEEK_END`)9394Значение по умолчанию для *start* – 0, что означает начало от начала файла. Значение по умолчанию для *length* – 0, что означает блокировку до конца файла. Значение по умолчанию для *whence* также равно 0.9596Примеры (все на системе, совместимой с SVR4):9798```python99import struct, fcntl, os100101f = open(...)102rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)103104lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)105rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)106```107108Обратите внимание, что в первом примере переменная *rv* будет содержать целое число, а во втором – строку. Структура данных для переменной *lockdata* зависит от системы – поэтому использование вызова [`flock()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.flock) может быть предпочтительнее.109110> **См. также**111>112> **Модуль [`os`](https://python-all.ru/3.0/library/os.html#module-os)**113>114> Если флаги блокировки115>116> `O_SHLOCK`117>118> и119>120> `O_EXLOCK`121>122> присутствуют в модуле123>124> [`os`](https://python-all.ru/3.0/library/os.html#module-os)125>126> , функция127>128> [`os.open()`](https://python-all.ru/3.0/library/os.html#os.open)129>130> предоставляет более платформонезависимую альтернативу функциям131>132> [`lockf()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.lockf)133>134> и135>136> [`flock()`](https://python-all.ru/3.0/library/fcntl.html#fcntl.flock)137>138> .139