作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等。这些最基础的计算机动作被称为指令 (instruction)。所谓的程序(program),就是这样一系列指令的所构成的集合。通过程序,我们可以让计算机完成复杂的操作。程序大多数时候被存储为可执行的文件。这样一个可执行文件就像是一个菜谱,计算机可以按照菜谱作出可口的饭菜。

那么,程序和进程(process)的区别又是什么呢?

进程是程序的一个具体实现。只有食谱没什么用,我们总要按照食谱的指点真正一步步实行,才能做出菜肴。进程是执行程序的过程,类似于按照食谱,真正去做菜的过程。同一个程序可以执行多次,每次都可以在内存中开辟独立的空间来装载,从而产生多个进程。不同的进程还可以拥有各自独立的IO接口。

操作系统的一个重要功能就是为进程提供方便,比如说为进程分配内存空间,管理进程的相关信息等等,就好像是为我们准备好了一个精美的厨房。

看一眼进程

首先,我们可以使用$ps命令来查询正在运行的进程,比如$ps -eo pid,comm,cmd,下图为执行结果:

(-e表示列出全部进程,-o pid,comm,cmd表示我们需要PID,COMMAND,CMD信息)

每一行代表了一个进程。每一行又分为三列。第一列PID(process IDentity)是一个整数,每一个进程都有一个唯一的PID来代表自己的身份,进程也可以根据PID来识别其他的进程。第二列COMMAND是这个进程的简称。第三列CMD是进程所对应的程序以及运行时所带的参数。

(第三列有一些由中括号[]括起来的。它们是内核的一部分功能,被打扮成进程的样子以方便操作系统管理。我们不必考虑它们。)

我们看第一行,PID为1,名字为init。这个进程是执行/bin/init这一文件(程序)生成的。当Linux启动的时候,init是系统创建的第一个进程,这一进程会一直存在,直到我们关闭计算机。这一进程有特殊的重要性,我们会不断提到它。

如何创建一个进程

实际上,当计算机开机的时候,内核(kernel)只建立了一个init进程。Linux内核并不提供直接建立新进程的系统调用。剩下的所有进程都是init进程通过fork机制建立的。新的进程要通过老的进程复制自身得到,这就是fork。fork是一个系统调用。进程存活于内存中。每个进程都在内存中分配有属于自己的一片空间 (address space)。当进程fork的时候,Linux在内存中开辟出一片新的内存空间给新的进程,并将老的进程空间中的内容复制到新的空间中,此后两个进程同时运行。

老进程成为新进程的父进程(parent process),而相应的,新进程就是老的进程的子进程(child process)。一个进程除了有一个PID之外,还会有一个PPID(parent PID)来存储的父进程PID。如果我们循着PPID不断向上追溯的话,总会发现其源头是init进程。所以说,所有的进程也构成一个以init为根的树状结构。

如下,我们查询当前shell下的进程:

root@vamei:~# ps -o pid,ppid,cmd

PID PPID CMD16935 3101 sudo -i16939 16935 -bash23774 16939 ps -o pid,ppid,cmd

我们可以看到,第二个进程bash是第一个进程sudo的子进程,而第三个进程ps是第二个进程的子进程。

还可以用$pstree命令来显示整个进程树:

init─┬─NetworkManager─┬─dhclient

│ └─2*[{NetworkManager}]

├─accounts-daemon───{accounts-daemon}

├─acpid

├─apache2─┬─apache2

│ └─2*[apache2───26*[{apache2}]]

├─at-spi-bus-laun───2*[{at-spi-bus-laun}]

├─atd

├─avahi-daemon───avahi-daemon

├─bluetoothd

├─colord───2*[{colord}]

├─console-kit-dae───64*[{console-kit-dae}]

├─cron

├─cupsd───2*[dbus]

├─2*[dbus-daemon]

├─dbus-launch

├─dconf-service───2*[{dconf-service}]

├─dropbox───15*[{dropbox}]

├─firefox───27*[{firefox}]

├─gconfd-2

├─geoclue-master

├─6*[getty]

├─gnome-keyring-d───7*[{gnome-keyring-d}]

├─gnome-terminal─┬─bash

│ ├─bash───pstree

│ ├─gnome-pty-helpe

│ ├─sh───R───{R}

│ └─3*[{gnome-terminal}]

fork通常作为一个函数被调用。这个函数会有两次返回,将子进程的PID返回给父进程,0返回给子进程。实际上,子进程总可以查询自己的PPID来知道自己的父进程是谁,这样,一对父进程和子进程就可以随时查询对方。

通常在调用fork函数之后,程序会设计一个if选择结构。当PID等于0时,说明该进程为子进程,那么让它执行某些指令,比如说使用exec库函数(library function)读取另一个程序文件,并在当前的进程空间执行 (这实际上是我们使用fork的一大目的: 为某一程序创建进程);而当PID为一个正整数时,说明为父进程,则执行另外一些指令。由此,就可以在子进程建立之后,让它执行与父进程不同的功能。

子进程的终结(termination)

当子进程终结时,它会通知父进程,并清空自己所占据的内存,并在内核里留下自己的退出信息(exit code,如果顺利运行,为0;如果有错误或异常状况,为>0的整数)。在这个信息里,会解释该进程为什么退出。父进程在得知子进程终结时,有责任对该子进程使用wait系统调用。这个wait函数能从内核中取出子进程的退出信息,并清空该信息在内核中所占据的空间。但是,如果父进程早于子进程终结,子进程就会成为一个孤儿(orphand)进程。孤儿进程会被过继给init进程,init进程也就成了该进程的父进程。init进程负责该子进程终结时调用wait函数。

当然,一个糟糕的程序也完全可能造成子进程的退出信息滞留在内核中的状况(父进程不对子进程调用wait函数),这样的情况下,子进程成为僵尸(zombie)进程。当大量僵尸进程积累时,内存空间会被挤占。

进程与线程(thread)

尽管在UNIX中,进程与线程是有联系但不同的两个东西,但在Linux中,线程只是一种特殊的进程。多个线程之间可以共享内存空间和IO接口。所以,进程是Linux程序的唯一的实现方式。

总结

程序,进程,PID,内存空间

子进程,父进程,PPID,fork, wait

cupsd进程_Linux进程基础相关推荐

  1. cupsd进程_Linux进程及作业管理

    Linux进程 进程(Process): 运行中的程序的一个副本 进程存在生命周期,程序是一个静态的文件 Linux内核存储进程信息的固定格式:task struct 多个任务的的task struc ...

  2. linux 查看java进程_Linux进程查看及管理工具(ps, vmstat, dstat, glances等)

    pstree pstree - display a tree of processes , 进程树查看. [root@localhost /]# pstree systemd─┬─agetty├─au ...

  3. 根据用户查进程_Linux进程之如何查看进程详情?

    来自:掘金,作者:RunFromHere 链接:https://juejin.im/post/5bf9213ce51d452237153c5c 1.ps是什么? 要对进程进行监测和控制,首先必须要了解 ...

  4. Linux进程的创建和父子进程同步,操作系统实验报告_Linux进程创建与通信.doc

    操作系统实验报告_Linux进程创建与通信 2011-2012学年第一学期 专 业: 班 级: 学 号: 姓 名:提交日期:2011年11月实验二 Linux进程创建与进程通信 [实验目的 1. 熟悉 ...

  5. 进程和线程基础知识(已经是最详细的啦)

    进程和线程基础知识 文章目录 进程和线程基础知识 一.前言 二.进程 1.引入 2.并发和并行有什么区别? 3.进程与程序的关系的类比 4.进程的状态 5.进程的控制结构 6.进程的控制 7.进程的上 ...

  6. Linux进程管理:进程和线程基础知识

    <Linux进程管理:进程和线程基础知识> <Linux-进程管理> <C语言进程的内存地址空间分配> <进程和线程模型> <(1)Linux进程 ...

  7. stopped状态的进程 top 命令_Linux 进程管理之四大名捕

    一.四大名捕 四大名捕,最初出现于温瑞安创作的武侠小说,是朝廷中正义力量诸葛小花的四大徒弟,四人各怀绝技,分别是轻功暗器高手"无情".内功卓越的高手"铁手".腿 ...

  8. linux 线程异常退出_Linux 进程必知必会

    只是简单的描述了一下 Linux 基本概念,通过几个例子来说明 Linux 基本应用程序,然后以 Linux 基本内核构造来结尾.那么本篇文章我们就深入理解一下 Linux 内核来理解 Linux 的 ...

  9. c++时间片轮转rr进程调度算法_进程,线程基础(—)

    进程 进程简单的定义是指装载到内存的指令集并且正在由cpu执行其中的每一条指令的这个程序叫做进程. 进程控制块 process control block 简称PCB,主要包含了标识符,状态,优先级, ...

  10. java并发编程-进程和线程调度基础

      弄清楚计算机底层进程.线程调度等原理对我们理解java并发编程有很大的帮助. 文章目录 1.什么是进程 2.什么是线程 3.进程和线程的区别与联系 4.CPU内核数和线程数的关系 5.CPU时间片 ...

最新文章

  1. PB程序“无法启动此程序,因为计算机中丢失PBvm90.dll。尝试重新安装该程序以解决此问题”的解决方法
  2. java 通配符 泛型_java中泛型之类型通配符(?)
  3. C++工作笔记-3种方法对数据类型进行拆分(可用于各种协议)
  4. django中admin路由系统工作原理
  5. 3dmax测试软件自动关闭,win7系统一打开3DMax2014软件就自动关闭的解决方法
  6. Arcgis desktop 9.3的破解方法(转载GIS帝国)
  7. redis灵魂拷问:为什么响应变慢了
  8. 有 4 件事,我很后悔
  9. mysql使用dual进行自定义数据查询
  10. 简单三步搭建公司内部论坛:安装部署Discuz 1-2
  11. 计算机网络基础基本知识
  12. FME校园培训南京站
  13. 精英主义 遗传算法 matlab,遗传算法优化 - osc_lfs4vsih的个人空间 - OSCHINA - 中文开源技术交流社区...
  14. SpringMvc文件上传和下载
  15. 数据库、MySQL的简介和使用
  16. oracle sql 获取当前时间,Oracle 在SQL语句中如何获取系统当前时间并进行操作
  17. ip代理软件竟然可以刷数据!!!
  18. 双重差分 difference-in-differences
  19. ModBusTcp协议(一)
  20. 2015年的计算机二级考试题,2015年计算机二级《MSOffice》试题及答案

热门文章

  1. 2.jenkins 新建一个任务
  2. 11.卷2(进程间通信)--- System V 信号量
  3. 13.nginx 源码目录及配置
  4. 3. Ubuntu LAMP 环境搭建
  5. 23. 变量、作用域和内存问题
  6. 编程语言 - PHP
  7. 「Django」contenttypes基本用法
  8. java Servlet文件拷贝的模板代码
  9. pytest学习(1)
  10. CAF(C++ actor framework)使用随笔(unbecome与keep_behavior用法)