进程状态





    <section powered-by="xiumi.us" style="margin: 0px; padding: 0px; color: rgb(62, 62, 62); text-transform: none; line-height: 25.6px; text-indent: 0px; letter-spacing: normal; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; word-spacing: 0px; white-space: normal; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; orphans: 2; widows: 2; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;">
        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        每一个进程拥有自己的状态,状态表示了进程当前在发生什么。

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        在进程的执行期间进程的状态会发生改变。一些进程的状态如下:

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        TASK_RUNNING

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        在此状态下,表示进程正在CPU中运行或在队列中等待运行(运行队列)。

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        TASK_STOPPED

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        在此状态下的进程被某些信号(如SIGINT,SIGSTOP)暂停。进程正在等待通过一个信号恢复运行,例如SIGCONT。

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        TASK_INTERRUPTIBLE

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        在此状态下,进程被暂停并等待一个某些条件状态的到达。如果一个进程处于TASK_INTERRUPTIBLE状态并接收到一个停止的信号,进程的状态将会被改变并中断操作。一个典型的TASK_INTERRUPTIBLE状态的进程的例子是一个进程等待键盘中断。

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        TASK_UNINTERRUPTIBLE

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        与TASK_INTERRUPTIBLE相似。当一个进程处于TASK_UNINTERRUPTIBLE状态可以被中断,向处于TASK_UNINTERRUPTIBLE状态的进程发送一个信号不会发生任何操作。一个TASK_UNINTERRUPTIBLE进程的典型的例子是等待磁盘I/O操作。

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        TASK_ZOMBIE

                </section>

                <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">

                        当一个进程调用exit()系统调用退出后,它的父进程应该知道该进程的终止。处于TASK_ZOMBIE状态的进程会等待其父进程通知其释放所有的数据结构。

                </section>
            </section>
        </section>
    </section>

    <section style="margin: 0px; padding: 0px; color: rgb(62, 62, 62); text-transform: none; line-height: 25.6px; text-indent: 0px; letter-spacing: normal; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; word-spacing: 0px; white-space: normal; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;">
        僵尸进程
    </section>

    <section style="margin: 0px; padding: 0px; color: rgb(62, 62, 62); text-transform: none; line-height: 25.6px; text-indent: 0px; letter-spacing: normal; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; word-spacing: 0px; white-space: normal; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;">
        当一个进程接收到一个信号而终止,它在结束自己之前,通常需要一些时间来结束所有的任务(例如关闭打开的文件)。在这个通常非常短暂的时间内,该进程就是一个僵尸进程。
    </section>

    <section style="margin: 0px; padding: 0px; color: rgb(62, 62, 62); text-transform: none; line-height: 25.6px; text-indent: 0px; letter-spacing: normal; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; word-spacing: 0px; white-space: normal; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;">
        进程已经完成所有的关闭任务后,它会向父进程报告其即将终止。有些时候,一个僵尸进程不能把自己终止,这将会引导它的状态显示为z(zombie)。
    </section>

    <section style="margin: 0px; padding: 0px; color: rgb(62, 62, 62); text-transform: none; line-height: 25.6px; text-indent: 0px; letter-spacing: normal; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; word-spacing: 0px; white-space: normal; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;">
        使用kill命令来关闭这样的一个进程是不可能的,因为该进程已经被认为已经死掉了。如果你不能清除僵尸进程,你可以结束其父进程,然后僵尸进程也随之消失。但是,如果父进程为init进程,你不能结束它。init进程是一个非常重要的进程,因此可能需要重启系统来清除僵尸进程。
    </section>

        &nbsp;

        &nbsp;

        &nbsp;

        &nbsp;

    <section style="background-position: 50% 50%; margin: 0px; padding: 0px; width: 20em; height: 3em; line-height: 3.2em; display: inline-block; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box; background-image: url(&quot;http://mmbiz.qpic.cn/mmbiz_png/IP70Vic417DML7HId9ogGy83xrI1SeAdcB1jIXkW2icAASyHsTSjL0BDyBwQIibgUww5N6oGmdUsMNrcK367hGM7w/0?wx_fmt=png&quot;); background-repeat: no-repeat; background-size: cover;">
        <section powered-by="xiumi.us" style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
                <section style="margin: 0px; padding: 0px; font-size: 24px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
                    进程内存段
                </section>
            </section>
        </section>
    </section>
</section>





进程使用其自身的内存区域来执行工作。工作的变化根据情况和进程的使用而决定。进程可以拥有不同的工作量特性和不同的数据大小需求。进程必须处理各种数据大小。为了满足需求,Linux内核为每个进程使用动态申请内存的机制。进程内存分配的数据结构如图1-7所示。











图1-7 进程地址空间
        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            进程内存区由以下几部分组成:
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            Text段
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            该区域用于存储运行代码。
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            Data段
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            数据段包括三个区域。
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            &ndash; Data:该区域存储已被初始化的数据,如静态变量。

            &ndash; BSS:该区域存储初始化为0的数据。数据被初始化为0。

            &ndash; Heap:该区域用于根据需求使用malloc()动态申请的内存。堆向高地址方向增长。
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            Stack段
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            该区域用于存储局部变量、函数参数和返回函数的地址。栈向低地址方向增长。
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            用户进程的地址空间内存分布可以使用pmap命令来查看。你可以使用ps命令来查看内存段的大小。可以参阅2.3.10的&ldquo;pmap&rdquo;,&ldquo;ps和pstree&rdquo;。
        </section>
    </section>
</section>







Linux CPU调度









任何的计算机的基本功能都非常简单,就是计算。为了能够计算,它意味着必须管理计算资源或处理器和计算任务,也就是我们所知道的线程或进程。感谢Ingo Molnar的巨大贡献,Linux内核使用一个O(1)的算法代替以前的O(n)的CPU调度算法。O(1)指的是一种静态的算法,意味着选择一个进程并执行所花费的时间是一个常数,不管进程的数量的大小。
        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            新的调度算法的扩展性非常好,不管进程的数量或者处理器的数量是多少,系统的开销都是非常少的。该算法使用两个进程优先级数组:
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            active(活动的)
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            expired(过期的)
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            调度器根据进程的优先级和优先拦截率为进程分配时间片,然后进程以优先级顺序放置到active数组内。当进程时间片耗尽,进程申请一个新的时间片并放置到expired数组内。当active数组中的所有进程的时间片耗尽,这两个数组进行切换,重新运行该算法。对于一般的交互式进程(相对于实时进程),拥有高优先级的进程通常比低优先级的进程得到更长的时间片和更多的计算时间,但这并不表示低优先级的进程会被完全忽略(饿死)。该算法的优势是为拥有大量线程和进程并拥有多处理器的企业级环境提升Linux内核的扩展性。该O(1)的新CPU调度器是为内存2.6设计的,但是现在已经移植到2.4系列中。图1-8说明了Linux CPU如何调度工作。
        </section>
    </section>
</section>









图1-8 Linux内核2.6 O(1)调度器
        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            新调度器的另一个显著改进是支持非一致性内存架构(NUMA)和对称多线程处理器,例如Intel超线程技术。
        </section>

        <section style="margin: 0px; padding: 0px; -ms-word-wrap: break-word !important; max-width: 100%; box-sizing: border-box;">
            改进后的NUMA支持确保只有某个节点过载时,负载平衡才会跨越某个NUMA节点。这个机制确保了在NUMA系统相对比较缓慢的扩展链接流量的最小化。尽管每个调度节拍时负载平衡会遍历调度域群组中的处理器,但只有在节点过载并请求负载平衡时,负载才会跨越调度域转移。
        </section>
    </section>
</section>










图1-9 O(1)CPU调度器结构

马哥Linux运维