计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等。这些最基础的计算机动作被称为指令 (instruction)。所谓的程序(program),就是这样一系列指令的所构成的集合。通过程序,我们可以让计算机完成复杂的操作。程序大多数时候被存储为可执行的文件。这样一个可执行文件就像是一个菜谱,计算机可以按照菜谱作出可口的饭菜。
那么,程序和进程(process)的区别又是什么呢?
进程是程序的一个具体实现。只有食谱没什么用,我们总要按照食谱的指点真正一步步实行,才能做出菜肴。进程是执行程序的过程,类似于按照食谱,真正去做菜的过程。同一个程序可以执行多次,每次都可以在内存中开辟独立的空间来装载,从而产生多个进程。不同的进程还可以拥有各自独立的IO接口。
操作系统的一个重要功能就是为进程提供方便,比如说为进程分配内存空间,管理进程的相关信息等等,就好像是为我们准备好了一个精美的厨房。
1. 看一眼进程
首先,我们可以使用$ps命令来查询正在运行的进程,比如$ps -eo pid,comm,cmd,下图为执行结果:
(-e表示列出全部进程,-o pid,comm,cmd表示我们需要PID,COMMAND,CMD信息)
每一行代表了一个进程。每一行又分为三列。第一列PID(process IDentity)是一个整数,每一个进程都有一个唯一的PID来代表自己的身份,进程也可以根据PID来识别其他的进程。第二列COMMAND是这个进程的简称。第三列CMD是进程所对应的程序以及运行时所带的参数。
(第三列有一些由中括号[]括起来的。它们是kernel的一部分功能,被打扮成进程的样子以方便操作系统管理。我们不必考虑它们。)
我们看第一行,PID为1,名字为init。这个进程是执行/bin/init这一文件(程序)生成的。当Linux启动的时候,init是系统创建的第一个进程,这一进程会一直存在,直到我们关闭计算机。这一进程有特殊的重要性,我们会不断提到它。
2. 如何创建一个进程
实际上,当计算机开机的时候,内核(kernel)只建立了一个init进程。Linux
kernel并不提供直接建立新进程的系统调用。剩下的所有进程都是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 CMD
16935 3101 sudo -i
16939 16935 -bash
23774 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为一个正整数时,说明为父进程,则执行另外一些指令。由此,就可以在子进程建立之后,让它执行与父进程不同的功能。
3.子进程的终结(termination)
当子进程终结时,它会通知父进程,并清空自己所占据的内存,并在kernel里留下自己的退出信息(exit code,如果顺利运行,为0;如果有错误或异常状况,为>0的整数)。在这个信息里,会解释该进程为什么退出。父进程在得知子进程终结时,有责任对该子进程使用wait系统调用。这个wait函数能从kernel中取出子进程的退出信息,并清空该信息在kernel中所占据的空间。但是,如果父进程早于子进程终结,子进程就会成为一个孤儿(orphand)进程。孤儿进程会被过继给init进程,init进程也就成了该进程的父进程。init进程负责该子进程终结时调用wait函数。
当然,一个糟糕的程序也完全可能造成子进程的退出信息滞留在kernel中的状况(父进程不对子进程调用wait函数),这样的情况下,子进程成为僵尸(zombie)进程。当大量僵尸进程积累时,内存空间会被挤占。
4.进程与线程(thread)
尽管在UNIX中,进程与线程是有联系但不同的两个东西,但在Linux中,线程只是一种特殊的进程。多个线程之间可以共享内存空间和IO接口。所以,进程是Linux程序的唯一的实现方式。
总结:
程序,进程,PID,内存空间
子进程,父进程,PPID,fork, wait
作者:Vamei出处:http://www.cnblogs.com/vamei欢迎转载,也请保留这段声明。谢谢!
分享到:
相关推荐
【Linux进程基础教程详解】 在计算机领域,进程是操作系统中非常重要的概念,它代表了程序在执行过程中的实例。在Linux系统中,了解进程的工作原理和管理方式对于系统管理和优化至关重要。本文将深入探讨Linux进程...
本教程通过6个视频,深入浅出地讲解了Linux进程间通信的关键概念和技术。 首先,我们来了解一下什么是进程间通信。在Linux系统中,进程是程序的一次执行实例,每个进程都有自己的独立内存空间,因此它们之间的数据...
Linux2.6.x 内核进程调度算法为解决实际问题,设计了全新的数据结构和调度算法,但其基本策路仍是以优先级为基础的抢占式调度。2.6 版本的内核调度也是几度变迁,其基本思想是提高实时进程调度相应比和普通进程调度...
在操作系统中,进程是最基本的独立运行单元,它为应用程序提供了资源管理和调度的基础。 #### 2. Linux 进程状态 Linux中的进程可以处于多种状态,这些状态反映了进程在系统中的生命周期: - **用户态运行**:进程...
操作系统实验报告(LINUX进程间通信) 操作系统实验报告(LINUX进程间通信)是操作系统课程的一部分,涵盖了Linux进程间通信的原理和应用,包括消息队列、C/S结构等内容。下面将对这些知识点进行详细的解释。 一、...
本文将详细探讨Linux进程编程的基础知识,包括进程的概念、创建与管理进程、进程间通信以及线程的使用。 首先,我们需要了解什么是进程。在操作系统中,进程是程序的执行实例,它包含了一段内存空间,包括代码、...
### LINUX进程管理实验知识点解析 #### 一、进程与程序的区别 在进行LINUX进程管理实验之前,首先需要理解进程与程序之间的区别。程序是指令的集合,是静态的,而进程则是程序的一次动态执行过程,具有生命周期,...
总的来说,Linux进程是系统运行的基础,涉及的知识点广泛且深入,包括进程的生命周期管理、内存管理和资源分配、进程间通信、调度策略等。通过阅读提供的PDF文档和相关文本资料,开发者可以进一步深化对Linux内核的...
### Linux进程源代码分析 #### 0. 引言 近年来,随着开源软件运动的兴起,Linux作为一种开放源码的操作系统,在技术社区中获得了广泛的关注和发展。Linux的开放性不仅促进了其自身的发展,也为广大开发者提供了...
Linux 进程编程基础 - 进程同步和进程通信 Linux 进程编程基础是计算机科学和软件工程中的一门重要课程,涉及到操作系统的核心内容。进程是操作系统中的一种基本概念,理解进程的概念和编程技术对于软件开发和系统...
【进程控制实验】是Linux操作系统课程中的一个重要环节,旨在...通过这些实验,学生不仅能理解进程的基本概念,还能实际操作和体验进程的创建、执行和通信过程,为后续学习进程同步、互斥、通信等高级主题奠定基础。
### Linux进程结构详解 在深入探讨Linux进程结构之前,我们首先需要明确,给出的示例似乎是基于Windows操作系统下的_EPROCESS结构描述,而非直接关联于Linux的进程结构。然而,这并不妨碍我们以此为引,详细解析...
Linux进程调度是操作系统核心部分,负责管理系统的CPU执行时间,确保所有进程都能公平地获取资源。在Linux 2.6.23内核版本中,引入了Completely Fair Scheduler(CFS)作为主要的调度器,取代了原有的调度策略。在...
在“ka.rar”这个压缩包中,包含了关于Linux进程调度、进程管理以及进程同步的相关实验和资料,这些都是理解和操作Linux系统至关重要的知识点。 首先,我们来看“进程调度”。在Linux中,进程调度器负责决定哪个...
本章主要讨论了Linux进程存储管理的各个方面,包括ANSI C内存管理API函数、常用的Linux内存管理和调试工具,以及Linux进程环境和系统限制。 首先,ANSI C内存管理API函数是C语言编程中进行动态内存分配的基础。它们...
本文将深入解析Linux进程间通信机制,通过源代码分析和流程图来帮助理解各种IPC方法。 首先,我们要理解进程的概念。在Linux系统中,进程是程序的一次执行实例,每个进程都有自己的内存空间,相互独立。为了实现...
综上所述,Linux进程管理涉及多个方面,包括进程控制块的结构设计、进程状态的管理、进程创建和终止的机制、进程调度策略以及进程间通信。掌握这些知识点对于深入理解Linux操作系统和进行系统编程都至关重要。
在Linux服务器管理中,进程管理是一项基础且至关重要的任务,它涉及到系统性能监控、资源调度以及问题排查。本文将深入探讨Linux的进程管理方法,特别是如何使用`ps`和`top`这两个命令来查看和监视进程状态。 首先...
【Linux进程之如何查看进程详情】\n\n在Linux操作系统中,管理和控制进程是系统管理员的基本任务之一。要实现这一目标,首要的就是了解当前运行的进程情况,这可以通过`ps`命令来完成。`ps`命令是Linux下查看进程...