67.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 295 行 · 第 1/2 页

HTML
295
字号
<a name='L125'>          <b>continue</b>;
<a name='L126'>        <b>if</b> (task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;pid != pid)
<a name='L127'>          <b>continue</b>;
<a name='L128'>        task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;signal |= (1 &lt;&lt; (<a href='../S/39.html#L30' title='Defined at 30 in include/signal.h.'>SIGCHLD</a> - 1));
<a name='L129'>        <b>return</b>;
<a name='L130'>      <font color='red'>}</font>
<a name='L131'><i><font color='green'>/* if we don't find any fathers, we just release ourselves */</font></i>
<a name='L132'><i><font color='green'>/* This is not really OK. Must change it to make father 1 */</font></i>
<a name='L133'>  <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("BAD BAD - no father found\n\r");
<a name='L134'>  <a href='../S/67.html#L22' title='Defined at 22 in kernel/exit.c.'>release</a> (current);            <i><font color='green'>// 如果没有找到父进程,则自己释放。</font></i>
<a name='L135'><font color='red'>}</font>
<a name='L136'>
<a name='L137'><i><font color='green'>//// 程序退出处理程序。在系统调用的中断处理程序中被调用。</font></i>
<a name='L138'><b>int</b>
<a name='L139'><a href='../R/437.html' title='Multiple refered from 8 places.'>do_exit</a> (<b>long</b> code)             <i><font color='green'>// code 是错误码。</font></i>
<a name='L140'><font color='red'>{</font>
<a name='L141'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L142'>
<a name='L143'><i><font color='green'>// 释放当前进程代码段和数据段所占的内存页(free_page_tables()在mm/memory.c,105 行)。</font></i>
<a name='L144'>  <a href='../S/94.html#L158' title='Defined at 158 in mm/memory.c.'>free_page_tables</a> (<a href='../S/36.html#L343' title='Defined at 343 in include/linux/sched.h.'>get_base</a> (current-&gt;ldt[1]), <a href='../S/36.html#L346' title='Defined at 346 in include/linux/sched.h.'>get_limit</a> (0x0f));
<a name='L145'>  <a href='../S/94.html#L158' title='Defined at 158 in mm/memory.c.'>free_page_tables</a> (<a href='../S/36.html#L343' title='Defined at 343 in include/linux/sched.h.'>get_base</a> (current-&gt;ldt[2]), <a href='../S/36.html#L346' title='Defined at 346 in include/linux/sched.h.'>get_limit</a> (0x17));
<a name='L146'><i><font color='green'>// 如果当前进程有子进程,就将子进程的father 置为1(其父进程改为进程1)。如果该子进程已经</font></i>
<a name='L147'><i><font color='green'>// 处于僵死(ZOMBIE)状态,则向进程1 发送子进程终止信号SIGCHLD。</font></i>
<a name='L148'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L149'>    <b>if</b> (task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] &amp;&amp; task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;father == current-&gt;pid)
<a name='L150'>      <font color='red'>{</font>
<a name='L151'>        task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;father = 1;
<a name='L152'>        <b>if</b> (task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;state == <a href='../S/36.html#L23' title='Defined at 23 in include/linux/sched.h.'>TASK_ZOMBIE</a>)
<a name='L153'><i><font color='green'>/* assumption task[1] is always init */</font></i>
<a name='L154'>          (<b>void</b>) <a href='../S/67.html#L41' title='Defined at 41 in kernel/exit.c.'>send_sig</a> (<a href='../S/39.html#L30' title='Defined at 30 in include/signal.h.'>SIGCHLD</a>, task[1], 1);
<a name='L155'>      <font color='red'>}</font>
<a name='L156'><i><font color='green'>// 关闭当前进程打开着的所有文件。</font></i>
<a name='L157'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/31.html#L59' title='Defined at 59 in include/linux/fs.h.'>NR_OPEN</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L158'>    <b>if</b> (current-&gt;filp[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L159'>      <a href='../S/15.html#L299' title='Defined at 299 in fs/open.c.'>sys_close</a> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>);
<a name='L160'><i><font color='green'>// 对当前进程工作目录pwd、根目录root 以及运行程序的i 节点进行同步操作,并分别置空。</font></i>
<a name='L161'>  <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (current-&gt;pwd);
<a name='L162'>  current-&gt;pwd = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L163'>  <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (current-&gt;root);
<a name='L164'>  current-&gt;root = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L165'>  <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (current-&gt;executable);
<a name='L166'>  current-&gt;executable = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L167'><i><font color='green'>// 如果当前进程是领头(leader)进程并且其有控制的终端,则释放该终端。</font></i>
<a name='L168'>  <b>if</b> (current-&gt;leader &amp;&amp; current-&gt;<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a> &gt;= 0)
<a name='L169'>    tty_table[current-&gt;<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>].pgrp = 0;
<a name='L170'><i><font color='green'>// 如果当前进程上次使用过协处理器,则将last_task_used_math 置空。</font></i>
<a name='L171'>  <b>if</b> (last_task_used_math == current)
<a name='L172'>    last_task_used_math = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L173'><i><font color='green'>// 如果当前进程是leader 进程,则终止所有相关进程。</font></i>
<a name='L174'>  <b>if</b> (current-&gt;leader)
<a name='L175'>    <a href='../S/67.html#L57' title='Defined at 57 in kernel/exit.c.'>kill_session</a> ();
<a name='L176'><i><font color='green'>// 把当前进程置为僵死状态,并设置退出码。</font></i>
<a name='L177'>  current-&gt;state = <a href='../S/36.html#L23' title='Defined at 23 in include/linux/sched.h.'>TASK_ZOMBIE</a>;
<a name='L178'>  current-&gt;exit_code = code;
<a name='L179'><i><font color='green'>// 通知父进程,也即向父进程发送信号SIGCHLD -- 子进程将停止或终止。</font></i>
<a name='L180'>  <a href='../S/67.html#L117' title='Defined at 117 in kernel/exit.c.'>tell_father</a> (current-&gt;father);
<a name='L181'>  <a href='../S/74.html#L146' title='Defined at 146 in kernel/sched.c.'>schedule</a> ();                  <i><font color='green'>// 重新调度进程的运行。</font></i>
<a name='L182'>  <b>return</b> (-1);                  <i><font color='green'>/* just to suppress warnings */</font></i>
<a name='L183'><font color='red'>}</font>
<a name='L184'>
<a name='L185'><i><font color='green'>//// 系统调用exit()。终止进程。</font></i>
<a name='L186'><b>int</b>
<a name='L187'><a href='../R/641.html' title='Multiple refered from 3 places.'>sys_exit</a> (<b>int</b> error_code)
<a name='L188'><font color='red'>{</font>
<a name='L189'>  <b>return</b> <a href='../S/67.html#L139' title='Defined at 139 in kernel/exit.c.'>do_exit</a> ((error_code &amp; 0xff) &lt;&lt; 8);
<a name='L190'><font color='red'>}</font>
<a name='L191'>
<a name='L192'><i><font color='green'>//// 系统调用waitpid()。挂起当前进程,直到pid 指定的子进程退出(终止)或者收到要求终止</font></i>
<a name='L193'><i><font color='green'>// 该进程的信号,或者是需要调用一个信号句柄(信号处理程序)。如果pid 所指的子进程早已</font></i>
<a name='L194'><i><font color='green'>// 退出(已成所谓的僵死进程),则本调用将立刻返回。子进程使用的所有资源将释放。</font></i>
<a name='L195'><i><font color='green'>// 如果pid &gt; 0, 表示等待进程号等于pid 的子进程。</font></i>
<a name='L196'><i><font color='green'>// 如果pid = 0, 表示等待进程组号等于当前进程的任何子进程。</font></i>
<a name='L197'><i><font color='green'>// 如果pid &lt; -1, 表示等待进程组号等于pid 绝对值的任何子进程。</font></i>
<a name='L198'><i><font color='green'>// [ 如果pid = -1, 表示等待任何子进程。]</font></i>
<a name='L199'><i><font color='green'>// 若options = WUNTRACED,表示如果子进程是停止的,也马上返回。</font></i>
<a name='L200'><i><font color='green'>// 若options = WNOHANG,表示如果没有子进程退出或终止就马上返回。</font></i>
<a name='L201'><i><font color='green'>// 如果stat_addr 不为空,则就将状态信息保存到那里。</font></i>
<a name='L202'><b>int</b>
<a name='L203'><a href='../R/696.html' title='Multiple refered from 2 places.'>sys_waitpid</a> (<a href='../S/45.html#L23' title='Defined at 23 in include/sys/types.h.'>pid_t</a> pid, <b>unsigned</b> <b>long</b> *stat_addr, <b>int</b> options)
<a name='L204'><font color='red'>{</font>
<a name='L205'>  <b>int</b> flag, code;
<a name='L206'>  <b>struct</b> task_struct **p;
<a name='L207'>
<a name='L208'>  <a href='../S/68.html#L34' title='Defined at 34 in kernel/fork.c.'>verify_area</a> (stat_addr, 4);
<a name='L209'>repeat:
<a name='L210'>  flag = 0;
<a name='L211'>  <b>for</b> (p = &amp;<a href='../S/36.html#L8' title='Defined at 8 in include/linux/sched.h.'>LAST_TASK</a>; p &gt; &amp;<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>; --p)
<a name='L212'>    <font color='red'>{</font>                           <i><font color='green'>// 从任务数组末端开始扫描所有任务。</font></i>
<a name='L213'>      <b>if</b> (!*p || *p == current) <i><font color='green'>// 跳过空项和本进程项。</font></i>
<a name='L214'>        <b>continue</b>;
<a name='L215'>      <b>if</b> ((*p)-&gt;father != current-&gt;pid) <i><font color='green'>// 如果不是当前进程的子进程则跳过。</font></i>
<a name='L216'>        <b>continue</b>;
<a name='L217'>      <b>if</b> (pid &gt; 0)
<a name='L218'>        <font color='red'>{</font>                       <i><font color='green'>// 如果指定的pid&gt;0,但扫描的进程pid</font></i>
<a name='L219'>          <b>if</b> ((*p)-&gt;pid != pid) <i><font color='green'>// 与之不等,则跳过。</font></i>
<a name='L220'>            <b>continue</b>;
<a name='L221'>        <font color='red'>}</font>
<a name='L222'>      <b>else</b> <b>if</b> (!pid)
<a name='L223'>        <font color='red'>{</font>                       <i><font color='green'>// 如果指定的pid=0,但扫描的进程组号</font></i>
<a name='L224'>          <b>if</b> ((*p)-&gt;pgrp != current-&gt;pgrp)      <i><font color='green'>// 与当前进程的组号不等,则跳过。</font></i>
<a name='L225'>            <b>continue</b>;
<a name='L226'>        <font color='red'>}</font>
<a name='L227'>      <b>else</b> <b>if</b> (pid != -1)
<a name='L228'>        <font color='red'>{</font>                       <i><font color='green'>// 如果指定的pid&lt;-1,但扫描的进程组</font></i>
<a name='L229'>          号if ((*p)-&gt;pgrp != -pid)     <i><font color='green'>// 与其绝对值不等,则跳过。</font></i>
<a name='L230'>            <b>continue</b>;
<a name='L231'>        <font color='red'>}</font>
<a name='L232'>      <b>switch</b> ((*p)-&gt;state)
<a name='L233'>        <font color='red'>{</font>
<a name='L234'>        <b>case</b> <a href='../S/36.html#L24' title='Defined at 24 in include/linux/sched.h.'>TASK_STOPPED</a>:
<a name='L235'>          <b>if</b> (!(options &amp; <a href='../S/47.html#L12' title='Defined at 12 in include/sys/wait.h.'>WUNTRACED</a>))
<a name='L236'>            <b>continue</b>;
<a name='L237'>          <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (0x7f, stat_addr);        <i><font color='green'>// 置状态信息为0x7f。</font></i>
<a name='L238'>          <b>return</b> (*p)-&gt;pid;     <i><font color='green'>// 退出,返回子进程的进程号。</font></i>
<a name='L239'>        <b>case</b> <a href='../S/36.html#L23' title='Defined at 23 in include/linux/sched.h.'>TASK_ZOMBIE</a>:
<a name='L240'>          current-&gt;cutime += (*p)-&gt;utime;       <i><font color='green'>// 更新当前进程的子进程用户</font></i>
<a name='L241'>          current-&gt;cstime += (*p)-&gt;stime;       <i><font color='green'>// 态和核心态运行时间。</font></i>
<a name='L242'>          flag = (*p)-&gt;pid;
<a name='L243'>          code = (*p)-&gt;exit_code;       <i><font color='green'>// 取子进程的退出码。</font></i>
<a name='L244'>          <a href='../S/67.html#L22' title='Defined at 22 in kernel/exit.c.'>release</a> (*p);         <i><font color='green'>// 释放该子进程。</font></i>
<a name='L245'>          <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (code, stat_addr);        <i><font color='green'>// 置状态信息为退出码值。</font></i>
<a name='L246'>          <b>return</b> flag;          <i><font color='green'>// 退出,返回子进程的pid.</font></i>
<a name='L247'>        <b>default</b>:
<a name='L248'>          flag = 1;             <i><font color='green'>// 如果子进程不在停止或僵死状态,则flag=1。</font></i>
<a name='L249'>          <b>continue</b>;
<a name='L250'>        <font color='red'>}</font>
<a name='L251'>    <font color='red'>}</font>
<a name='L252'>  <b>if</b> (flag)
<a name='L253'>    <font color='red'>{</font>                           <i><font color='green'>// 如果子进程没有处于退出或僵死状态,</font></i>
<a name='L254'>      <b>if</b> (options &amp; <a href='../S/47.html#L11' title='Defined at 11 in include/sys/wait.h.'>WNOHANG</a>)    <i><font color='green'>// 并且options = WNOHANG,则立刻返回。</font></i>
<a name='L255'>        <b>return</b> 0;
<a name='L256'>      current-&gt;state = <a href='../S/36.html#L21' title='Defined at 21 in include/linux/sched.h.'>TASK_INTERRUPTIBLE</a>;      <i><font color='green'>// 置当前进程为可中断等待状态。</font></i>
<a name='L257'>      <a href='../S/74.html#L146' title='Defined at 146 in kernel/sched.c.'>schedule</a> ();              <i><font color='green'>// 重新调度。</font></i>
<a name='L258'>      <b>if</b> (!(current-&gt;signal &amp;= ~(1 &lt;&lt; (<a href='../S/39.html#L30' title='Defined at 30 in include/signal.h.'>SIGCHLD</a> - 1))))  <i><font color='green'>// 又开始执行本进程时,</font></i>
<a name='L259'>        <b>goto</b> repeat;            <i><font color='green'>// 如果进程没有收到除SIGCHLD 的信号,则还是重复处理。</font></i>
<a name='L260'>      <b>else</b>
<a name='L261'>        <b>return</b> -<a href='../S/28.html#L33' title='Defined at 33 in include/errno.h.'>EINTR</a>;          <i><font color='green'>// 退出,返回出错码。</font></i>
<a name='L262'>    <font color='red'>}</font>
<a name='L263'>  <b>return</b> -<a href='../S/28.html#L39' title='Defined at 39 in include/errno.h.'>ECHILD</a>;
<a name='L264'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L22'>[^]</a><a href='#L203'>[v]</a><a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>

⌨️ 快捷键说明

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