⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 living_without_forks.html

📁 ADI 公司blackfin系列的用户使用文挡。
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>  <title></title>  <link rel="stylesheet" media="screen" type="text/css" href="./style.css" />  <link rel="stylesheet" media="screen" type="text/css" href="./design.css" />  <link rel="stylesheet" media="print" type="text/css" href="./print.css" />  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><div class="toc"><div class="tocheader toctoggle" id="toc__header">Table of Contents</div><div id="toc__inside"><ul class="toc"><li class="clear"><ul class="toc"><li class="level2"><div class="li"><span class="li"><a href="#we_have_no_fork" class="toc">We have no Fork</a></span></div><ul class="toc"><li class="level3"><div class="li"><span class="li"><a href="#some_examples" class="toc">Some Examples</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#webservers" class="toc">Webservers</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#stubborn_cases" class="toc">Stubborn Cases</a></span></div></li></ul></li></ul></li></ul></div></div><h2><a name="we_have_no_fork" id="we_have_no_fork">We have no Fork</a></h2><div class="level2"><p> In the early days ( late 1990&rsquo;s )  <strong>uClinux</strong> was scorned by a few because , without a <strong>MMU</strong>, it could not do a true <strong>fork</strong>.</p><p>The  <strong>fork</strong> system call  is the mechanism by which every single <strong>UNIX</strong> process normally gets started. Every process is, in fact, a clone of the first process started by the booting kernel.</p><p>A <strong>fork</strong> produces a <strong>parent</strong> and <strong>child</strong>. Each have individual task control structures and each can be scheduled independently by the kernel. When we have an MMU the parent and child eventually occupy different physical memory spaces. The MMU maps different physical memory addresses to identical virtual memory addresses and copies the data from parent to child. Under Linux this happens when either process attepmts to write to a shared physical memory area.</p><p>On a typical system this <strong>cloneing</strong> can work because immediately after the <strong>fork</strong> the  child  replaces the parent&rsquo;s program with a new executable. Sometimes the <strong>parent</strong> and <strong>child</strong> are supposed to be identical at first but operating on different data. </p><p> <strong>uClinux</strong> does not have the functionality of a true <strong>fork</strong>. It does have a close cousin the <strong>vfork</strong> system call.</p><p>When a <strong>vfork</strong> system call is made the <strong>parent</strong> task is halted and a new task control block created using the same text memory, stack, and data memory as the <strong>parent</strong>. The new <strong>child</strong> then has to replace its program and data areas with an <strong>execve</strong> call or it has to <strong>exit</strong> before the parent is allowed to continue.</p><p> The <strong>execve</strong> system call is one of a series of <strong>exec</strong> system calls that all have different arrangements of arguments and envronment variables. </p><pre class="code"> Try this man 2 execl </pre><p> The purpose of this call is to use the same kernel space task control block but run a different program under that control block. The text and data are read from an executable file specified in one of the arguments and the new program starts from the defined <strong>start</strong> location specified in the new executable.</p><p>Once the new program memory has been established the parent task is released.</p></div><!-- SECTION [1-2105] --><h3><a name="some_examples" id="some_examples">Some Examples</a></h3><div class="level3"><p> The uClinux Distribution contains many good examples of using <strong>vfork</strong>.</p><p>The <strong>simpleinit</strong> program ( which is the first user code executed by the kernel after boot) is given the job of running all the initial programs required by the system.</p><p>Here is an extract where it is booting to single user mode and trying to run a <strong>shell</strong>  program.</p><pre class="code"></pre><pre class="code c">    <span class="co1">// part of the &quot;boot to single user &quot;code </span>&nbsp;    av<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = _PATH_BSHELL;        <span class="co1">// /bin/sh</span>    av<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = <span class="kw2">NULL</span>;    <span class="kw1">if</span><span class="br0">&#40;</span><span class="br0">&#40;</span>pid = vfork<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>  <span class="co1">// pid = 0 in the child</span>    <span class="kw2">extern</span> <span class="kw4">char</span> **environ;        <span class="coMULTI">/* the child */</span>        execve<span class="br0">&#40;</span>_PATH_BSHELL, av, environ<span class="br0">&#41;</span>;  <span class="co1">// if this works parent is released</span>        err<span class="br0">&#40;</span><span class="st0">"exec of single user shell failed<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;        _exit<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>;                           <span class="co1">// if execve failed exit releases parent</span>    <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span><span class="br0">&#40;</span>pid &gt; <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>    <span class="kw4">int</span> i;                                   <span class="co1">// this is the parent</span>        <span class="kw1">while</span><span class="br0">&#40;</span>wait<span class="br0">&#40;</span>&amp;i<span class="br0">&#41;</span> != pid<span class="br0">&#41;</span> <span class="coMULTI">/* nothing */</span>;    <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span><span class="br0">&#40;</span>pid &lt; <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>        err<span class="br0">&#40;</span><span class="st0">"fork of single user shell failed<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;    <span class="br0">&#125;</span>    <span class="co1">//parent continues, the child has execve'd a new program.</span></pre><p> Another example</p><pre class="code c">&nbsp;<span class="kw4">static</span> <span class="kw4">int</span> do_command<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span> *path, <span class="kw4">const</span> <span class="kw4">char</span> *filename, <span class="kw4">int</span> dowait<span class="br0">&#41;</span><span class="br0">&#123;</span>        pid_t pid, wpid;        <span class="kw4">int</span> stat, st;&nbsp;        <span class="kw1">if</span><span class="br0">&#40;</span><span class="br0">&#40;</span>pid = vfork<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>                <span class="coMULTI">/* the child */</span>                <span class="kw4">char</span> *argv<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>;                <span class="kw4">char</span> *env<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>;&nbsp;                close<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>;                argv<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = <span class="br0">&#40;</span><span class="kw4">char</span> *<span class="br0">&#41;</span>path;                argv<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = <span class="br0">&#40;</span><span class="kw4">char</span> *<span class="br0">&#41;</span>filename;                argv<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> = <span class="kw2">NULL</span>;&nbsp;                env<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = <span class="st0">"PATH=/bin:/usr/bin:/etc:/sbin:/usr/sbin"</span>;                env<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = <span class="kw2">NULL</span>;                execve<span class="br0">&#40;</span>path, argv, env<span class="br0">&#41;</span>;                   err<span class="br0">&#40;</span><span class="st0">"exec rc failed<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;                _exit<span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span>;&nbsp;        <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span><span class="br0">&#40;</span>pid &gt; <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>  <span class="co1">// parent</span>                <span class="kw1">if</span> <span class="br0">&#40;</span>!dowait<span class="br0">&#41;</span> <span class="br0">&#123;</span>                        stat = <span class="nu0">0</span>;                <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>                        <span class="coMULTI">/* parent, wait till rc process dies before spawning */</span>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -