35.9. fcntl
- fcntl
和ioctl
系统调用¶
该模块对文件描述器执行文件控制和I / O控制。它是fcntl()
和ioctl()
Unix例程的接口。有关这些调用的完整说明,请参阅fcntl(2)和ioctl(2) Unix手册页。
该模块中的所有函数都接受一个文件描述器fd作为它们的第一个参数。这可以是整型文件描述器,例如由sys.stdin.fileno()
或io.IOBase
对象返回,如sys.stdin
本身,它提供了一个fileno()
,返回一个真正的文件描述器。
该模块定义了以下功能:
-
fcntl.
fcntl
(fd, cmd, arg=0)¶ 在文件描述器fd上执行操作cmd(也接受提供
fileno()
方法的文件对象)。用于cmd的值与操作系统有关,可在fcntl
模块中使用常量,使用与相关C头文件中使用的名称相同的名称。参数arg可以是整数值,也可以是bytes
对象。对于整数值,此函数的返回值是Cfcntl()
调用的整数返回值。当参数是字节时,它表示二进制结构,例如。由struct.pack()
创建。二进制数据被复制到其地址被传递到Cfcntl()
调用的缓冲器。成功调用后的返回值是缓冲区的内容,转换为bytes
对象。返回的对象的长度将与arg参数的长度相同。这被限制为1024字节。如果操作系统在缓冲区中返回的信息大于1024字节,则这很可能导致分段违规或更微妙的数据损坏。如果
fcntl()
失败,则会引发OSError
。
-
fcntl.
ioctl
(fd, request, arg=0, mutate_flag=True)¶ 此函数与
fcntl()
函数相同,只是参数处理更复杂。请求参数限制为可以容纳32位的值。用作请求参数的其他常用常量可在
termios
模块中找到,其名称与相关C头文件中使用的相同。The parameter arg can be one of an integer, an object supporting the read-only buffer interface (like
bytes
) or an object supporting the read-write buffer interface (likebytearray
).除了最后一种情况,所有行为都与
fcntl()
函数相同。如果传递了可变缓冲区,则该行为由mutate_flag参数的值确定。
如果为false,则忽略缓冲区的可变性,并且行为与只读缓冲区相同,只是避免了上面提到的1024字节限制 - 只要缓冲区通过的时间至少与操作系统所期望的一样长在那里,事情应该工作。
如果mutate_flag为true(默认值),则缓冲区(实际上)传递给底层的
ioctl()
系统调用,后者的返回代码会传递回调用Python,缓冲区的新内容反映了ioctl()
的操作。这是一个小小的简化,因为如果提供的缓冲区小于1024字节长,它首先被复制到静态缓冲区1024字节长,然后传递到ioctl()
并复制回提供的缓冲区。如果
ioctl()
失败,则会引发OSError
异常。一个例子:
>>> import array, fcntl, struct, termios, os >>> os.getpgrp() 13341 >>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, " "))[0] 13341 >>> buf = array.array('h', [0]) >>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1) 0 >>> buf array('h', [13341])
-
fcntl.
flock
(fd, operation)¶ 在文件描述器fd上执行锁操作操作(也接受提供
fileno()
方法的文件对象)。有关详细信息,请参阅Unix手册flock(2)。(在某些系统上,使用fcntl()
来模拟此函数。)如果
flock()
失败,则会引发OSError
异常。
-
fcntl.
lockf
(fd, cmd, len=0, start=0, whence=0)¶ 这本质上是
fcntl()
锁定调用的包装。fd是要锁定或解锁的文件的描述器,cmd是以下值之一:LOCK_UN
- 解锁LOCK_SH
- 获取共享锁LOCK_EX
- 获取独占锁
当cmd为
LOCK_SH
或LOCK_EX
时,也可以与LOCK_NB
进行位或运算以避免锁定获取时阻塞。如果使用LOCK_NB
并且无法获取锁定,则会引发OSError
,并且异常将将errno属性设置为EACCES
或EAGAIN
(取决于操作系统;对于可移植性,请检查两个值)。在至少某些系统上,只有当文件描述器引用一个打开的写入文件时,才能使用LOCK_EX
。len是要锁定的字节数,start是锁定开始的字节偏移量,相对于whence和whence 与
io.IOBase.seek()
一样,具体为:0
- 相对于文件的开头(os.SEEK_SET
)1
- 相对于当前缓冲位置(os.SEEK_CUR
)2
- 相对于文件结尾(os.SEEK_END
)
start的默认值为0,表示从文件开头开始。len的默认值为0,表示锁定到文件的结尾。whence的默认值也为0。
示例(全部在SVR4兼容系统上):
import struct, fcntl, os
f = open(...)
rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)
lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)
注意,在第一个例子中,返回值变量rv将保存一个整数值;在第二个示例中,它将保存一个bytes
对象。lockdata变量的结构布局取决于系统,因此使用flock()
调用可能更好。