18 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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">fcntl2</em><em class="manpage">ioctl2</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">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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">flock2</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>