fcntl
fcntl - fcntl和ioctl系统调用
该模块对文件描述符执行文件控制和I / O控制。它是fcntl()
和ioctl()
Unix例程的接口。有关这些调用的完整说明,请参阅fcntl(2)
和ioctl(2)
Unix手册页。
该模块中的所有函数都将文件描述符fd作为其第一个参数。 这可以是一个整数文件描述符,例如sys.stdin.fileno()返回的整数文件描述符,或者是一个文件对象,比如sys.stdin本身,它提供了一个fileno(),它返回一个真正的文件描述符。
该模块定义了以下功能:
fcntl.fcntl(fd, op[, arg])
对文件描述符fd执行操作op(也接受提供fileno()方法的文件对象)。用于for的值取决于操作系统,可在fcntl模块中作为常量使用,使用与相关C头文件中使用的名称相同的名称。参数arg是可选的,默认为整数值0.存在时,它可以是整数值或字符串。缺少参数或整数值时,此函数的返回值是C fcntl()调用的整数返回值。当参数是一个字符串时,它表示二进制结构,例如由struct.pack()创建。二进制数据被复制到一个缓冲区,该缓冲区的地址被传递给C fcntl()调用。成功调用后的返回值是缓冲区的内容,转换为字符串对象。返回的字符串的长度将与arg参数的长度相同。这限制为1024字节。如果操作系统在缓冲区中返回的信息大于1024字节,这很可能导致分段违规或更微妙的数据损坏。
如果fcntl()
失败,则提出IOError
。
fcntl.ioctl(fd, op[, arg[, mutate_flag]])
该函数与fcntl()函数相同,除了操作通常在库模块termios中定义并且参数处理更加复杂。
op参数限制为可以适合32位的值。 用作op参数的其他常量可以在termios模块中找到,其名称与相关C头文件中使用的名称相同。
参数arg可以是整数,不存在(与整数0相同),支持只读缓冲区接口(很可能是纯Python字符串)的对象或支持读写缓冲区接口的对象之一。
除最后一种情况外,其行为与fcntl()
功能一样。
如果传递了一个可变缓冲区,则行为由mutate_flag
参数的值决定。
如果它是错误的,那么缓冲区的可变性将被忽略,行为与只读缓冲区相同,只是上面提到的1024字节限制是可以避免的 - 只要你传递的缓冲区至少和操作系统想要的一样长时间放在那里,则应该工作。
如果mutate_flag为true,那么缓冲区(实际上)传递给基础的ioctl()系统调用,后者的返回代码被传回给调用的Python,并且缓冲区的新内容反映ioctl()的动作。 这是一个小的简化,因为如果提供的缓冲区长度小于1024字节,它首先被复制到1024字节长的静态缓冲区中,然后传递给ioctl()并将其复制回提供的缓冲区。
如果没有提供mutate_flag
,那么从Python 2.5开始默认为true,这是从版本2.3和2.4的变化。如果版本可移植性是优先级,则明确提供参数。
如果ioctl()
失败,则会引发IOError
异常。
一个例子:
>>> 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, op)
在文件描述符fd上执行锁操作op(也接受提供fileno()方法的文件对象)。 有关详细信息,请参见Unix手册(2)。 (在某些系统上,这个函数是用fcntl()模拟的。)
如果flock()
失败,则会引发IOError
异常。
fcntl.lockf(fd, operation[, length[, start[, whence]]])
这本质上是fcntl()
锁定调用的一个包装。fd
是要锁定或解锁的文件的文件描述符,并且操作
是以下值之一:
LOCK_UN
- 开锁
LOCK_SH
- 获得共享锁
LOCK_EX
- 获得独家锁定
当操作是LOCK_SH或LOCK_EX时,它也可以与LOCK_NB按位或运算,以避免在锁定采集时阻塞。 如果使用LOCK_NB并且无法获取锁,则会引发IOError,并且该异常的errno属性将设置为EACCES或EAGAIN(取决于操作系统;为便于携带,请检查这两个值)。 至少在某些系统上,只有在文件描述符指向为写入而打开的文件时才能使用LOCK_EX。
length是要锁定的字节数,start是锁开始的字节偏移量,相对于此,以及与io.IOBase.seek()相同,具体为:
0
- 相对于文件的开始(os.SEEK_SET
)
1
- 相对于当前缓冲区的位置(os.SEEK_CUR
)
2
- 相对于文件的结尾(os.SEEK_END
)
start
的默认值是0,这意味着从文件的开头开始。length
的默认值为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
将保存一个整数值; 在第二个例子中它将保存一个字符串值。lockdata
变量的结构布局是依赖于系统的 - 因此使用这个flock()
调用可能会更好。
扩展内容
模块操作系统如果os模块中存在锁定标志O_SHLOCK和O_EXLOCK(仅在BSD上),os.open()函数提供了lockf()和flock()函数的替代方法。