“Python/docs/3.9/library/fcntl”的版本间差异
(autoload) |
小 (Page commit) |
||
第1行: | 第1行: | ||
+ | {{DISPLAYTITLE:fcntl — fcntl 和 ioctl 系统调用 — Python 文档}} | ||
<div id="module-fcntl" class="section"> | <div id="module-fcntl" class="section"> | ||
<span id="fcntl-the-fcntl-and-ioctl-system-calls"></span> | <span id="fcntl-the-fcntl-and-ioctl-system-calls"></span> | ||
− | = | + | = fcntl — fcntl 和 ioctl 系统调用 = |
− | |||
− | |||
− | |||
− | |||
− | + | ----- | |
− | + | ||
− | <code>sys.stdin.fileno()</code> | + | 该模块对文件描述符执行文件控制和 I/O 控制。 它是 <code>fcntl()</code> 和 <code>ioctl()</code> Unix 例程的接口。 有关这些调用的完整说明,请参阅 ''fcntl(2)'' 和 ''ioctl(2)'' Unix 手册页。 |
− | + | ||
− | + | 该模块中的所有函数都将文件描述符 ''fd'' 作为它们的第一个参数。 这可以是一个整数文件描述符,例如由 <code>sys.stdin.fileno()</code> 返回,或一个 [[../io#io|io.IOBase]] 对象,例如 <code>sys.stdin</code> 本身,它提供了一个 [[../io#io.IOBase|fileno( )]] 返回一个真正的文件描述符。 | |
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <span class="versionmodified changed">在 3.3 | + | <span class="versionmodified changed">在 3.3 版中更改:</span>此模块中的操作用于引发 [[../exceptions#IOError|IOError]],它们现在引发 [[../exceptions#OSError|OSError]]。 |
− | |||
第24行: | 第20行: | ||
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <span class="versionmodified changed"> | + | <span class="versionmodified changed"> 3.8 版更改: </span> fcntl 模块现在包含 <code>F_ADD_SEALS</code>、<code>F_GET_SEALS</code> 和 <code>F_SEAL_*</code> 常量,用于密封 os.memfd_create()[ X145X] 文件描述符。 |
− | <code>F_SEAL_*</code> | ||
− | |||
第32行: | 第26行: | ||
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <span class="versionmodified changed"> | + | <span class="versionmodified changed"> 3.9 更改: </span> 在 macOS 上,fcntl 模块公开了 <code>F_GETPATH</code> 常量,该常量从文件描述符中获取文件的路径。 在 Linux(>=3.15) 上,fcntl 模块公开了 <code>F_OFD_GETLK</code>、<code>F_OFD_SETLK</code> 和 <code>F_OFD_SETLKW</code> 常量,这些常量与打开的文件描述锁一起使用。 |
− | |||
− | |||
− | |||
</div> | </div> | ||
− | + | 该模块定义了以下功能: | |
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">fcntl.</span></span><span class="sig-name descname"><span class="pre">fcntl</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">cmd</span></span>'', ''<span class="n"><span class="pre">arg</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>对文件描述符 ''fd'' 执行操作 ''cmd''(也接受提供 [[../io#io.IOBase|fileno()]] 方法的文件对象)。 用于 ''cmd'' 的值取决于操作系统,并且在 [[#module-fcntl|fcntl]] 模块中作为常量提供,使用与相关 C 头文件中使用的名称相同的名称。 参数 ''arg'' 可以是整数值,也可以是 [[../stdtypes#bytes|bytes]] 对象。 使用整数值,该函数的返回值是C<code>fcntl()</code>调用的整数返回值。 当参数是字节时,它表示一个二进制结构,例如 由 [[../struct#struct|struct.pack()]] 创建。 二进制数据被复制到一个缓冲区,其地址被传递给 C <code>fcntl()</code> 调用。 成功调用后的返回值是缓冲区的内容,转换为 [[../stdtypes#bytes|bytes]] 对象。 返回对象的长度将与 ''arg'' 参数的长度相同。 这被限制为 1024 字节。 如果操作系统在缓冲区中返回的信息大于 1024 字节,这很可能会导致分段违规或更细微的数据损坏。</p> |
− | + | <p>如果 <code>fcntl()</code> 失败,则会引发 [[../exceptions#OSError|OSError]]。</p></dd></dl> | |
− | |||
− | |||
− | |||
− | [[../stdtypes#bytes| | ||
− | |||
− | |||
− | [[../struct#struct| | ||
− | |||
− | |||
− | |||
− | ''arg'' | ||
− | |||
− | |||
− | |||
− | <p> | ||
− | |||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">fcntl.</span></span><span class="sig-name descname"><span class="pre">ioctl</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">request</span></span>'', ''<span class="n"><span class="pre">arg</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span>'', ''<span class="n"><span class="pre">mutate_flag</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>该函数与 [[#fcntl.fcntl|fcntl()]] 函数相同,只是参数处理更加复杂。</p> |
− | + | <p>''request'' 参数仅限于可以容纳 32 位的值。 可以在 [[../termios#module-termios|termios]] 模块中找到用作 ''request'' 参数的其他感兴趣的常量,其名称与相关 C 头文件中使用的名称相同。</p> | |
− | <p> | + | <p>参数 ''arg'' 可以是整数、支持只读缓冲区接口的对象(如 [[../stdtypes#bytes|bytes]])或支持读写缓冲区接口的对象(如 [[../stdtypes#bytearray|)之一字节数组]])。</p> |
− | + | <p>除了最后一种情况外,所有行为都与 [[#fcntl.fcntl|fcntl()]] 函数相同。</p> | |
− | + | <p>如果传递了可变缓冲区,则行为由 ''mutate_flag'' 参数的值决定。</p> | |
− | + | <p>如果为 false,则缓冲区的可变性将被忽略,行为与只读缓冲区相同,只是避免了上面提到的 1024 字节限制——只要你传递的缓冲区至少与操作系统想要的一样长放在那里,事情应该工作。</p> | |
− | <p> | + | <p>如果 ''mutate_flag'' 为 true(默认值),则缓冲区(实际上)传递给底层 [[#fcntl.ioctl|ioctl()]] 系统调用,后者的返回码传递回调用 Python ,缓冲区的新内容反映了 [[#fcntl.ioctl|ioctl()]] 的操作。 这是一个轻微的简化,因为如果提供的缓冲区长度小于 1024 字节,则首先将其复制到 1024 字节长的静态缓冲区中,然后将其传递给 [[#fcntl.ioctl|ioctl()]] 并复制回提供的缓冲区中。</p> |
− | + | <p>如果 <code>ioctl()</code> 失败,则会引发 [[../exceptions#OSError|OSError]] 异常。</p> | |
− | + | <p>一个例子:</p> | |
− | <p> | ||
− | |||
− | <p> | ||
− | |||
− | <p> | ||
− | |||
− | |||
− | |||
− | <p> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | <p> | ||
− | <p> | ||
<div class="highlight-python3 notranslate"> | <div class="highlight-python3 notranslate"> | ||
<div class="highlight"> | <div class="highlight"> | ||
− | < | + | <syntaxhighlight lang="python3">>>> import array, fcntl, struct, termios, os |
− | + | >>> os.getpgrp() | |
13341 | 13341 | ||
− | + | >>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, " "))[0] | |
13341 | 13341 | ||
− | + | >>> buf = array.array('h', [0]) | |
− | + | >>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1) | |
0 | 0 | ||
− | + | >>> buf | |
− | array('h', [13341])</ | + | array('h', [13341])</syntaxhighlight> |
</div> | </div> | ||
− | </div | + | </div></dd></dl> |
− | |||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">fcntl.</span></span><span class="sig-name descname"><span class="pre">flock</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">operation</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>对文件描述符 ''fd'' 执行锁定操作 ''operation''(也接受提供 [[../io#io.IOBase|fileno()]] 方法的文件对象)。 有关详细信息,请参阅 Unix 手册 ''flock(2)''。 (在某些系统上,使用 <code>fcntl()</code> 模拟此功能。)</p> |
− | + | <p>如果 <code>flock()</code> 失败,则会引发 [[../exceptions#OSError|OSError]] 异常。</p></dd></dl> | |
− | '' | ||
− | |||
− | <p> | ||
− | |||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">fcntl.</span></span><span class="sig-name descname"><span class="pre">lockf</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">cmd</span></span>'', ''<span class="n"><span class="pre">len</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span>'', ''<span class="n"><span class="pre">start</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span>'', ''<span class="n"><span class="pre">whence</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>这本质上是对 [[#fcntl.fcntl|fcntl()]] 锁定调用的封装。 ''fd'' 是要锁定或解锁的文件的文件描述符(也接受提供 [[../io#io.IOBase|fileno()]] 方法的文件对象),''cmd'' 是其中之一以下值:</p> |
− | ''fd'' | ||
− | |||
− | |||
<ul> | <ul> | ||
− | <li><p><code>LOCK_UN</code> | + | <li><p><code>LOCK_UN</code> – 解锁</p></li> |
− | <li><p><code>LOCK_SH</code> | + | <li><p><code>LOCK_SH</code> – 获取共享锁</p></li> |
− | <li><p><code>LOCK_EX</code> | + | <li><p><code>LOCK_EX</code> – 获取排他锁</p></li></ul> |
− | <p> | + | <p>当 ''cmd'' 为 <code>LOCK_SH</code> 或 <code>LOCK_EX</code> 时,也可以与 <code>LOCK_NB</code> 进行按位或运算,以避免锁获取阻塞。 如果使用 <code>LOCK_NB</code> 并且无法获取锁,则会引发 [[../exceptions#OSError|OSError]] 并且异常会将 ''errno'' 属性设置为 <code>EACCES</code> 或<code>EAGAIN</code>(取决于操作系统;为了可移植性,检查两个值)。 至少在某些系统上,<code>LOCK_EX</code> 只能在文件描述符引用为写入而打开的文件时使用。</p> |
− | + | <p>''len'' 是要锁定的字节数,''start'' 是锁定开始的字节偏移量,相对于 ''whence'' 和 ''whence''与 [[../io#io.IOBase|io.IOBase.seek()]] 一样,特别是:</p> | |
− | |||
− | [[../exceptions#OSError| | ||
− | |||
− | |||
− | |||
− | |||
− | <p>''len'' | ||
− | |||
− | [[../io#io.IOBase| | ||
<ul> | <ul> | ||
− | <li><p><code>0</code> | + | <li><p><code>0</code> – 相对于文件的开头 ([[../os#os|os.SEEK_SET]])</p></li> |
− | <li><p><code>1</code> | + | <li><p><code>1</code> – 相对于当前缓冲区位置 ([[../os#os|os.SEEK_CUR]])</p></li> |
− | <li><p><code>2</code> | + | <li><p><code>2</code> – 相对于文件结尾 ([[../os#os|os.SEEK_END]])</p></li></ul> |
− | <p> | + | <p>''start'' 的默认值为 0,表示从文件的开头开始。 ''len'' 的默认值为 0,表示锁定到文件末尾。 ''whence'' 的默认值也是 0。</p></dd></dl> |
− | |||
− | |||
− | |||
− | + | 示例(均在 SVR4 兼容系统上): | |
<div class="highlight-python3 notranslate"> | <div class="highlight-python3 notranslate"> | ||
第157行: | 第95行: | ||
<div class="highlight"> | <div class="highlight"> | ||
− | < | + | <syntaxhighlight lang="python3">import struct, fcntl, os |
f = open(...) | f = open(...) | ||
第163行: | 第101行: | ||
lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) | lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) | ||
− | rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)</ | + | rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)</syntaxhighlight> |
</div> | </div> | ||
</div> | </div> | ||
− | + | 请注意,在第一个示例中,返回值变量 ''rv'' 将保存一个整数值; 在第二个示例中,它将保存一个 [[../stdtypes#bytes|bytes]] 对象。 ''lockdata'' 变量的结构布局取决于系统——因此使用 [[#fcntl.flock|flock()]] 调用可能更好。 | |
− | |||
− | |||
− | |||
<div class="admonition seealso"> | <div class="admonition seealso"> | ||
− | + | 也可以看看 | |
− | ; | + | ; 模块 [[../os#module-os|os]] |
− | : | + | : 如果锁定标志 [[../os#os|O_SHLOCK]] 和 [[../os#os|O_EXLOCK]] 存在于 [[../os#module-os|os]] 模块中(仅在 BSD 上),则 [[../os#os|os.open()]] 函数提供了 [[#fcntl.lockf|lockf()]] 和 [[#fcntl.flock|flock()]] 函数的替代方法。 |
</div> | </div> | ||
+ | |||
+ | </div> | ||
+ | <div class="clearer"> | ||
+ | |||
+ | |||
</div> | </div> | ||
− | [[Category:Python 3.9 | + | [[Category:Python 3.9 文档]] |
2021年10月31日 (日) 04:52的最新版本
fcntl — fcntl 和 ioctl 系统调用
该模块对文件描述符执行文件控制和 I/O 控制。 它是 fcntl()
和 ioctl()
Unix 例程的接口。 有关这些调用的完整说明,请参阅 fcntl(2) 和 ioctl(2) Unix 手册页。
该模块中的所有函数都将文件描述符 fd 作为它们的第一个参数。 这可以是一个整数文件描述符,例如由 sys.stdin.fileno()
返回,或一个 io.IOBase 对象,例如 sys.stdin
本身,它提供了一个 fileno( ) 返回一个真正的文件描述符。
3.8 版更改: fcntl 模块现在包含 F_ADD_SEALS
、F_GET_SEALS
和 F_SEAL_*
常量,用于密封 os.memfd_create()[ X145X] 文件描述符。
3.9 更改: 在 macOS 上,fcntl 模块公开了 F_GETPATH
常量,该常量从文件描述符中获取文件的路径。 在 Linux(>=3.15) 上,fcntl 模块公开了 F_OFD_GETLK
、F_OFD_SETLK
和 F_OFD_SETLKW
常量,这些常量与打开的文件描述锁一起使用。
该模块定义了以下功能:
- fcntl.fcntl(fd, cmd, arg=0)
对文件描述符 fd 执行操作 cmd(也接受提供 fileno() 方法的文件对象)。 用于 cmd 的值取决于操作系统,并且在 fcntl 模块中作为常量提供,使用与相关 C 头文件中使用的名称相同的名称。 参数 arg 可以是整数值,也可以是 bytes 对象。 使用整数值,该函数的返回值是C
fcntl()
调用的整数返回值。 当参数是字节时,它表示一个二进制结构,例如 由 struct.pack() 创建。 二进制数据被复制到一个缓冲区,其地址被传递给 Cfcntl()
调用。 成功调用后的返回值是缓冲区的内容,转换为 bytes 对象。 返回对象的长度将与 arg 参数的长度相同。 这被限制为 1024 字节。 如果操作系统在缓冲区中返回的信息大于 1024 字节,这很可能会导致分段违规或更细微的数据损坏。如果
fcntl()
失败,则会引发 OSError。
- fcntl.ioctl(fd, request, arg=0, mutate_flag=True)
该函数与 fcntl() 函数相同,只是参数处理更加复杂。
request 参数仅限于可以容纳 32 位的值。 可以在 termios 模块中找到用作 request 参数的其他感兴趣的常量,其名称与相关 C 头文件中使用的名称相同。
参数 arg 可以是整数、支持只读缓冲区接口的对象(如 bytes)或支持读写缓冲区接口的对象(如 )之一字节数组)。
除了最后一种情况外,所有行为都与 fcntl() 函数相同。
如果传递了可变缓冲区,则行为由 mutate_flag 参数的值决定。
如果为 false,则缓冲区的可变性将被忽略,行为与只读缓冲区相同,只是避免了上面提到的 1024 字节限制——只要你传递的缓冲区至少与操作系统想要的一样长放在那里,事情应该工作。
如果 mutate_flag 为 true(默认值),则缓冲区(实际上)传递给底层 ioctl() 系统调用,后者的返回码传递回调用 Python ,缓冲区的新内容反映了 ioctl() 的操作。 这是一个轻微的简化,因为如果提供的缓冲区长度小于 1024 字节,则首先将其复制到 1024 字节长的静态缓冲区中,然后将其传递给 ioctl() 并复制回提供的缓冲区中。
如果
ioctl()
失败,则会引发 OSError 异常。一个例子:
- fcntl.flock(fd, operation)
对文件描述符 fd 执行锁定操作 operation(也接受提供 fileno() 方法的文件对象)。 有关详细信息,请参阅 Unix 手册 flock(2)。 (在某些系统上,使用
fcntl()
模拟此功能。)如果
flock()
失败,则会引发 OSError 异常。
- fcntl.lockf(fd, cmd, len=0, start=0, whence=0)
这本质上是对 fcntl() 锁定调用的封装。 fd 是要锁定或解锁的文件的文件描述符(也接受提供 fileno() 方法的文件对象),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 兼容系统上):
请注意,在第一个示例中,返回值变量 rv 将保存一个整数值; 在第二个示例中,它将保存一个 bytes 对象。 lockdata 变量的结构布局取决于系统——因此使用 flock() 调用可能更好。