mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
18 lines
20 KiB
HTML
18 lines
20 KiB
HTML
<div class="body" role="main"><div class="section" id="module-fcntl"><h1><span class="yiyi-st" id="yiyi-10">35.9. <a class="reference internal" href="#module-fcntl" title="fcntl: The fcntl() and ioctl() system calls. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">fcntl</span></code></a> - <code class="docutils literal"><span class="pre">fcntl</span></code>和<code class="docutils literal"><span class="pre">ioctl</span></code>系统调用</span></h1><p><span class="yiyi-st" id="yiyi-11">该模块对文件描述器执行文件控制和I / O控制。</span><span class="yiyi-st" id="yiyi-12">它是<code class="xref c c-func docutils literal"><span class="pre">fcntl()</span></code>和<code class="xref c c-func docutils literal"><span class="pre">ioctl()</span></code> Unix例程的接口。</span><span class="yiyi-st" id="yiyi-13">有关这些调用的完整说明,请参阅<em class="manpage">fcntl(2)</em>和<em class="manpage">ioctl(2)</em> Unix手册页。</span></p><p><span class="yiyi-st" id="yiyi-14">该模块中的所有函数都接受一个文件描述器<em>fd</em>作为它们的第一个参数。</span><span class="yiyi-st" id="yiyi-15">这可以是整型文件描述器,例如由<code class="docutils literal"><span class="pre">sys.stdin.fileno()</span></code>或<a class="reference internal" href="io.html#io.IOBase" title="io.IOBase"><code class="xref py py-class docutils literal"><span class="pre">io.IOBase</span></code></a>对象返回,如<code class="docutils literal"><span class="pre">sys.stdin</span></code>本身,它提供了一个<a class="reference internal" href="io.html#io.IOBase.fileno" title="io.IOBase.fileno"><code class="xref py py-meth docutils literal"><span class="pre">fileno()</span></code></a>,返回一个真正的文件描述器。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-16"><span class="versionmodified">在版本3.3中更改:</span>此模块中的操作用于引入<a class="reference internal" href="exceptions.html#IOError" title="IOError"><code class="xref py py-exc docutils literal"><span class="pre">IOError</span></code></a>,其中他们现在引入<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span></p></div><p><span class="yiyi-st" id="yiyi-17">该模块定义了以下功能:</span></p><dl class="function"><dt id="fcntl.fcntl"><span class="yiyi-st" id="yiyi-18"> <code class="descclassname">fcntl.</code><code class="descname">fcntl</code><span class="sig-paren">(</span><em>fd</em>, <em>cmd</em>, <em>arg=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-19">在文件描述器<em>fd</em>上执行操作<em>cmd</em>(也接受提供<a class="reference internal" href="io.html#io.IOBase.fileno" title="io.IOBase.fileno"><code class="xref py py-meth docutils literal"><span class="pre">fileno()</span></code></a>方法的文件对象)。</span><span class="yiyi-st" id="yiyi-20">用于<em>cmd</em>的值与操作系统有关,可在<a class="reference internal" href="#module-fcntl" title="fcntl: The fcntl() and ioctl() system calls. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">fcntl</span></code></a>模块中使用常量,使用与相关C头文件中使用的名称相同的名称。</span><span class="yiyi-st" id="yiyi-21">参数<em>arg</em>可以是整数值,也可以是<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象。</span><span class="yiyi-st" id="yiyi-22">对于整数值,此函数的返回值是C <code class="xref c c-func docutils literal"><span class="pre">fcntl()</span></code>调用的整数返回值。</span><span class="yiyi-st" id="yiyi-23">当参数是字节时,它表示二进制结构,例如。</span><span class="yiyi-st" id="yiyi-24">由<a class="reference internal" href="struct.html#struct.pack" title="struct.pack"><code class="xref py py-func docutils literal"><span class="pre">struct.pack()</span></code></a>创建。</span><span class="yiyi-st" id="yiyi-25">二进制数据被复制到其地址被传递到C <code class="xref c c-func docutils literal"><span class="pre">fcntl()</span></code>调用的缓冲器。</span><span class="yiyi-st" id="yiyi-26">成功调用后的返回值是缓冲区的内容,转换为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象。</span><span class="yiyi-st" id="yiyi-27">返回的对象的长度将与<em>arg</em>参数的长度相同。</span><span class="yiyi-st" id="yiyi-28">这被限制为1024字节。</span><span class="yiyi-st" id="yiyi-29">如果操作系统在缓冲区中返回的信息大于1024字节,则这很可能导致分段违规或更微妙的数据损坏。</span></p><p><span class="yiyi-st" id="yiyi-30">如果<code class="xref c c-func docutils literal"><span class="pre">fcntl()</span></code>失败,则会引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span></p></dd></dl><dl class="function"><dt id="fcntl.ioctl"><span class="yiyi-st" id="yiyi-31"> <code class="descclassname">fcntl.</code><code class="descname">ioctl</code><span class="sig-paren">(</span><em>fd</em>, <em>request</em>, <em>arg=0</em>, <em>mutate_flag=True</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-32">此函数与<a class="reference internal" href="#fcntl.fcntl" title="fcntl.fcntl"><code class="xref py py-func docutils literal"><span class="pre">fcntl()</span></code></a>函数相同,只是参数处理更复杂。</span></p><p><span class="yiyi-st" id="yiyi-33"><em>请求</em>参数限制为可以容纳32位的值。</span><span class="yiyi-st" id="yiyi-34">用作<em>请求</em>参数的其他常用常量可在<a class="reference internal" href="termios.html#module-termios" title="termios: POSIX style tty control. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">termios</span></code></a>模块中找到,其名称与相关C头文件中使用的相同。</span></p><p><span class="yiyi-st" id="yiyi-35">The parameter <em>arg</em> can be one of an integer, an object supporting the read-only buffer interface (like <a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>) or an object supporting the read-write buffer interface (like <a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a>).</span></p><p><span class="yiyi-st" id="yiyi-36">除了最后一种情况,所有行为都与<a class="reference internal" href="#fcntl.fcntl" title="fcntl.fcntl"><code class="xref py py-func docutils literal"><span class="pre">fcntl()</span></code></a>函数相同。</span></p><p><span class="yiyi-st" id="yiyi-37">如果传递了可变缓冲区,则该行为由<em>mutate_flag</em>参数的值确定。</span></p><p><span class="yiyi-st" id="yiyi-38">如果为false,则忽略缓冲区的可变性,并且行为与只读缓冲区相同,只是避免了上面提到的1024字节限制 - 只要缓冲区通过的时间至少与操作系统所期望的一样长在那里,事情应该工作。</span></p><p><span class="yiyi-st" id="yiyi-39">如果<em>mutate_flag</em>为true(默认值),则缓冲区(实际上)传递给底层的<a class="reference internal" href="#fcntl.ioctl" title="fcntl.ioctl"><code class="xref py py-func docutils literal"><span class="pre">ioctl()</span></code></a>系统调用,后者的返回代码会传递回调用Python,缓冲区的新内容反映了<a class="reference internal" href="#fcntl.ioctl" title="fcntl.ioctl"><code class="xref py py-func docutils literal"><span class="pre">ioctl()</span></code></a>的操作。</span><span class="yiyi-st" id="yiyi-40">这是一个小小的简化,因为如果提供的缓冲区小于1024字节长,它首先被复制到静态缓冲区1024字节长,然后传递到<a class="reference internal" href="#fcntl.ioctl" title="fcntl.ioctl"><code class="xref py py-func docutils literal"><span class="pre">ioctl()</span></code></a>并复制回提供的缓冲区。</span></p><p><span class="yiyi-st" id="yiyi-41">如果<code class="xref c c-func docutils literal"><span class="pre">ioctl()</span></code>失败,则会引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>异常。</span></p><p><span class="yiyi-st" id="yiyi-42">一个例子:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">array</span><span class="o">,</span> <span class="nn">fcntl</span><span class="o">,</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">termios</span><span class="o">,</span> <span class="nn">os</span>
|
||
<span class="gp">>>> </span><span class="n">os</span><span class="o">.</span><span class="n">getpgrp</span><span class="p">()</span>
|
||
<span class="go">13341</span>
|
||
<span class="gp">>>> </span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'h'</span><span class="p">,</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">ioctl</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">termios</span><span class="o">.</span><span class="n">TIOCGPGRP</span><span class="p">,</span> <span class="s2">" "</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="go">13341</span>
|
||
<span class="gp">>>> </span><span class="n">buf</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="s1">'h'</span><span class="p">,</span> <span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
||
<span class="gp">>>> </span><span class="n">fcntl</span><span class="o">.</span><span class="n">ioctl</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">termios</span><span class="o">.</span><span class="n">TIOCGPGRP</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="go">0</span>
|
||
<span class="gp">>>> </span><span class="n">buf</span>
|
||
<span class="go">array('h', [13341])</span>
|
||
</code></pre></dd></dl><dl class="function"><dt id="fcntl.flock"><span class="yiyi-st" id="yiyi-43"> <code class="descclassname">fcntl.</code><code class="descname">flock</code><span class="sig-paren">(</span><em>fd</em>, <em>operation</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-44">在文件描述器<em>fd</em>上执行锁操作<em>操作</em>(也接受提供<a class="reference internal" href="io.html#io.IOBase.fileno" title="io.IOBase.fileno"><code class="xref py py-meth docutils literal"><span class="pre">fileno()</span></code></a>方法的文件对象)。</span><span class="yiyi-st" id="yiyi-45">有关详细信息,请参阅Unix手册<em class="manpage">flock(2)</em>。</span><span class="yiyi-st" id="yiyi-46">(在某些系统上,使用<code class="xref c c-func docutils literal"><span class="pre">fcntl()</span></code>来模拟此函数。)</span></p><p><span class="yiyi-st" id="yiyi-47">如果<code class="xref c c-func docutils literal"><span class="pre">flock()</span></code>失败,则会引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>异常。</span></p></dd></dl><dl class="function"><dt id="fcntl.lockf"><span class="yiyi-st" id="yiyi-48"> <code class="descclassname">fcntl.</code><code class="descname">lockf</code><span class="sig-paren">(</span><em>fd</em>, <em>cmd</em>, <em>len=0</em>, <em>start=0</em>, <em>whence=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-49">这本质上是<a class="reference internal" href="#fcntl.fcntl" title="fcntl.fcntl"><code class="xref py py-func docutils literal"><span class="pre">fcntl()</span></code></a>锁定调用的包装。</span><span class="yiyi-st" id="yiyi-50"><em>fd</em>是要锁定或解锁的文件的描述器,<em>cmd</em>是以下值之一:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-51"><code class="xref py py-const docutils literal"><span class="pre">LOCK_UN</span></code> - 解锁</span></li><li><span class="yiyi-st" id="yiyi-52"><code class="xref py py-const docutils literal"><span class="pre">LOCK_SH</span></code> - 获取共享锁</span></li><li><span class="yiyi-st" id="yiyi-53"><code class="xref py py-const docutils literal"><span class="pre">LOCK_EX</span></code> - 获取独占锁</span></li></ul><p><span class="yiyi-st" id="yiyi-54">当<em>cmd</em>为<code class="xref py py-const docutils literal"><span class="pre">LOCK_SH</span></code>或<code class="xref py py-const docutils literal"><span class="pre">LOCK_EX</span></code>时,也可以与<code class="xref py py-const docutils literal"><span class="pre">LOCK_NB</span></code>进行位或运算以避免锁定获取时阻塞。</span><span class="yiyi-st" id="yiyi-55">如果使用<code class="xref py py-const docutils literal"><span class="pre">LOCK_NB</span></code>并且无法获取锁定,则会引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>,并且异常将将<em>errno</em>属性设置为<code class="xref py py-const docutils literal"><span class="pre">EACCES</span></code>或<code class="xref py py-const docutils literal"><span class="pre">EAGAIN</span></code>(取决于操作系统;对于可移植性,请检查两个值)。</span><span class="yiyi-st" id="yiyi-56">在至少某些系统上,只有当文件描述器引用一个打开的写入文件时,才能使用<code class="xref py py-const docutils literal"><span class="pre">LOCK_EX</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-57"><em>len</em>是要锁定的字节数,<em>start</em>是锁定开始的字节偏移量,相对于<em>whence</em>和<em>whence </em>与<a class="reference internal" href="io.html#io.IOBase.seek" title="io.IOBase.seek"><code class="xref py py-func docutils literal"><span class="pre">io.IOBase.seek()</span></code></a>一样,具体为:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-58"><code class="xref py py-const docutils literal"><span class="pre">0</span></code> - 相对于文件的开头(<a class="reference internal" href="os.html#os.SEEK_SET" title="os.SEEK_SET"><code class="xref py py-data docutils literal"><span class="pre">os.SEEK_SET</span></code></a>)</span></li><li><span class="yiyi-st" id="yiyi-59"><code class="xref py py-const docutils literal"><span class="pre">1</span></code> - 相对于当前缓冲位置(<a class="reference internal" href="os.html#os.SEEK_CUR" title="os.SEEK_CUR"><code class="xref py py-data docutils literal"><span class="pre">os.SEEK_CUR</span></code></a>)</span></li><li><span class="yiyi-st" id="yiyi-60"><code class="xref py py-const docutils literal"><span class="pre">2</span></code> - 相对于文件结尾(<a class="reference internal" href="os.html#os.SEEK_END" title="os.SEEK_END"><code class="xref py py-data docutils literal"><span class="pre">os.SEEK_END</span></code></a>)</span></li></ul><p><span class="yiyi-st" id="yiyi-61"><em>start</em>的默认值为0,表示从文件开头开始。</span><span class="yiyi-st" id="yiyi-62"><em>len</em>的默认值为0,表示锁定到文件的结尾。</span><span class="yiyi-st" id="yiyi-63"><em>whence</em>的默认值也为0。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-64">示例(全部在SVR4兼容系统上):</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">fcntl</span><span class="o">,</span> <span class="nn">os</span>
|
||
|
||
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
||
<span class="n">rv</span> <span class="o">=</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">fcntl</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">F_SETFL</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_NDELAY</span><span class="p">)</span>
|
||
|
||
<span class="n">lockdata</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">'hhllhh'</span><span class="p">,</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">F_WRLCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="n">rv</span> <span class="o">=</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">fcntl</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">F_SETLKW</span><span class="p">,</span> <span class="n">lockdata</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-65">注意,在第一个例子中,返回值变量<em>rv</em>将保存一个整数值;在第二个示例中,它将保存一个<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象。</span><span class="yiyi-st" id="yiyi-66"><em>lockdata</em>变量的结构布局取决于系统,因此使用<a class="reference internal" href="#fcntl.flock" title="fcntl.flock"><code class="xref py py-func docutils literal"><span class="pre">flock()</span></code></a>调用可能更好。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-67">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-68">模块<a class="reference internal" href="os.html#module-os" title="os: Miscellaneous operating system interfaces."><code class="xref py py-mod docutils literal"><span class="pre">os</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-69">If the locking flags <a class="reference internal" href="os.html#os.O_SHLOCK" title="os.O_SHLOCK"><code class="xref py py-data docutils literal"><span class="pre">O_SHLOCK</span></code></a> and <a class="reference internal" href="os.html#os.O_EXLOCK" title="os.O_EXLOCK"><code class="xref py py-data docutils literal"><span class="pre">O_EXLOCK</span></code></a> are present in the <a class="reference internal" href="os.html#module-os" title="os: Miscellaneous operating system interfaces."><code class="xref py py-mod docutils literal"><span class="pre">os</span></code></a> module (on BSD only), the <a class="reference internal" href="os.html#os.open" title="os.open"><code class="xref py py-func docutils literal"><span class="pre">os.open()</span></code></a> function provides an alternative to the <a class="reference internal" href="#fcntl.lockf" title="fcntl.lockf"><code class="xref py py-func docutils literal"><span class="pre">lockf()</span></code></a> and <a class="reference internal" href="#fcntl.flock" title="fcntl.flock"><code class="xref py py-func docutils literal"><span class="pre">flock()</span></code></a> functions.</span></dd></dl></div></div></div> |