1、进程标识

每个进程都有一个非负整型表示的唯一的进程ID。进程ID标识符总是唯一的

 虽然进程ID是唯一的,但某个ID被回收后,ID号是可以复用的。

ID为0的进程通常是调度进程(其常常被称交换进程)是系统进程。进程 1通常是init进程,在自举过程结束时由内核调用。init进程绝不会终止,是一个普通的用户进程但以超级用户进程特权运行。

除了进程id,进程还有其他标识符,

Linux中通过以下函数返回这些标识符(这些函数都是系统调用)。

#include <unistd.h>

pid_t getpid (void) ; //返回进程ID
pid_t getppid (void); //返回父进程ID
uid_t getuid (void) ; //返回实际用户ID
uid_t geteuid (void) ; //返回有效用户ID
gid_t getgid (void) ; //返回实际组ID
gid_t getegid (void) ; //返回有效组ID

2、fork函数

一个现有的进程可以调用fork函数创建一个新进程:pid_t fork (void) ;  fork创建的新进程被称为子进程。fork函数调用一次,但返回两次。两次返回的区别是子进程的返回值是0,父进程的返回值是新建子进程的进程id。子进程是父进程的副本,子进程获得父进程所有数据、堆栈。

3、exec函数

fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?exec 函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件。

进程退出表示进程即将结束。在Linux中进程退出分为了正常退出和异常退出两种。

1>正常退出

a. 在main()函数中执行return 。

b.调用exit()函数

c.调用_exit()函数

2>异常退出

a.调用about函数

b.进程收到了某个退出信号

退出时系统最终都会执行内核中的同一代码。这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存和其他资源。

3>比较以上几种退出方式的不同点

(1)exit和return 的区别:

a.exit是一个函数,有参数。exit执行完后把控制权交给系统

b.return是函数执行完后的返回。renturn执行完后把控制权交给调用函数。

(2)exit和abort的区别:

a.exit是正常终止进程

b.about是异常终止。

3>exit()和_exit()的区别:

a._exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。

b. 调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr  ...).   exit函数是在_exit函数之上的一个封装,其会调用_exit,并在调用之前先刷新流。

exit()函数与_exit()函数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区的内容写回文件。由于Linux的标准函数库中,有一种被称作“缓冲I/O”的操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续的读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区读取;同样,每次写文件的时候也仅仅是写入内存的缓冲区,等满足了一定的条件(如达到了一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也给编程代来了一点儿麻烦。比如有一些数据,认为已经写入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区的数据就会丢失。因此,要想保证数据的完整性,就一定要使用exit()函数。

#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("using exit----\n");
printf("This is the content in buffer\n");
exit();
}

结果:

using exit----
This is the content in buffer

//_exit.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
printf("using _exit----\n");
printf("This is the content in buffer");
_exit(0);
}

  

将代码中的printf("This is the content in buffer");改为

printf("This is the content in buffer\n")

using __exit----
This is the content in buffer

Tiger-John说明:

printf函数就是使用缓冲I/O的方式,该函数在遇到“\n”换行符时自动的从缓冲区中将记录读出。所以exit()将缓冲区的数据写完后才退出,而_exit()函数直接退出。

补充:

父子进程终止的先后顺序不同会产生不同的结果。

1>父进程先于子进程终止:

此种情况就是我们前面所用的孤儿进程。当父进程先退出时,系统会让init进程接管子进程 。

2>子进程先于父进程终止,而父进程又没有调用wait函数

此种情况子进程进入僵死状态,并且会一直保持下去直到系统重启。子进程处于僵死状态时,内核只保存进程的一些必要信息以备父进程所需。此时子进程始终占有着资源,同时也减少了系统可以创建的最大进程数。

什么是 僵死状态呢?

一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占有的资源)的进程被称为僵死进程(zombie)。ps命令将僵死进程的状态打印为Z

3> 子进程先于父进程终止,而父进程调用了wait函数

此时父进程会等待子进程结束。

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止,当然 如果在调用wait()时子进程已经结束,如果该父进程没有子进程或者它的子进程已经结束,则wait()函数就会立即返回。

waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程(它可以指定需要等待终止的子进程),它还有若干选项,如可提供一个非阻塞版本的 wait()功能,也能支持作业控制。实际上,wait()函数只是 waitpid()函数的一个特例,在Linux 内部实现 wait()函数时直接调用的就是waitpid()函数。

原:

http://blog.csdn.net/sdustliyang/article/details/6858624

http://blog.csdn.net/mybelief321/article/details/9066359

http://www.cnblogs.com/newlist/archive/2012/02/08/2342148.html

linux中进程控制的更多相关文章

  1. [转]Linux中进程内存与cgroup内存的统计

    From: http://hustcat.github.io/about/ Linux中进程内存与cgroup内存的统计 在Linux内核,对于进程的内存使用与Cgroup的内存使用统计有一些相同和不 ...

  2. Linux中进程控制块PCB-------task_struct结构体结构

    Linux中task_struct用来控制管理进程,结构如下: struct task_struct { //说明了该进程是否可以执行,还是可中断等信息 volatile long state; // ...

  3. Linux/UNIX进程控制(1)

    进程控制(1) 进程标识符 每一个进程都有肺腑的整形表示唯一的进程ID.按一个进程终止后,其进程ID就能够再次使用了.例如以下是几个典型进程的ID及其类型和功能. ID     进程名         ...

  4. 第十二章:Linux中权限控制实例

    前言 前文对 Linux 中的权限进行了较为透彻的分析.而本文,则在前文的基础上,具体说明如何在代码中进行权限控制. 下面的代码涉及到以下几个方面: 1. 创建文件时设置文件权限 2. 修改文件的默认 ...

  5. Linux中进程的优先级

    Linux採用两种不同的优先级范围,一种是nice值.还有一种是实时优先级. 1.nice值 nice值得范围是-20~19,默认值是0. 越大的nice值意味着更低的优先级.也就是说nice值为-2 ...

  6. Linux 中权限控制实例

    前言 前文对 Linux 中的权限进行了较为透彻的分析.而本文,则在前文的基础上,具体说明如何在代码中进行权限控制. 下面的代码涉及到以下几个方面: 1. 创建文件时设置文件权限 2. 修改文件的默认 ...

  7. 『学了就忘』Linux系统管理 — 82、Linux中进程的查看(ps命令)

    目录 1.ps命令介绍 2.ps aux命令示例 3.ps -le命令示例 4.pstree命令 1.ps命令介绍 ps命令是用来静态显示系统中进程的命令. 不过这个命令有些特殊,它部分命令的选项前不 ...

  8. 『学了就忘』Linux系统管理 — 83、Linux中进程的查看(top命令)

    目录 1.top命令介绍 2.top命令示例 3.top命令输出项解释 4.top命令常用的实例 1.top命令介绍 top命令是用来动态显示系统中进程的命令. [root@localhost ~]# ...

  9. Linux 中进程的管理

    Linux 的进程信号 1  HUP  挂起 2  INT  中断 3 QUIT  结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能终止 17 STOP 无条件终止运 ...

随机推荐

  1. 从python中copy与deepcopy的区别看python引用

    讨论copy与deepcopy的区别这个问题要先搞清楚python中的引用.python的内存管理. python中的一切事物皆为对象,并且规定参数的传递都是对象的引用.可能这样说听起来比较难懂,对比 ...

  2. 利用K2和Microsoft Dynamics CRM构建业务App的5大理由

    Microsoft Dynamics CRM提供了一个绝佳的客户关系管理平台,使您能够创建各种以客户为中心的解决方案.然而,通过将K2的企业业务流程功能与Microsoft Dynamics CRM相 ...

  3. Sketchup+ArcGIS三维建模与管理

    一.软件安装及其说明 1.需要安装的软件及其安装: 这份报告主要涉及到的有三个需要安装的软件ArcGIS9.3(或9.2) .Sketchup6.0和SketchUp6 ESRI 插件. ArcGIS ...

  4. 13个优秀的开源UML工具介绍

    本文将为您介绍12个优秀的UML工具: 1. StarUML StarUML(简称SU),是一种创建UML类图,是一种生成类图和其他类型的统一建模语言(UML)图表的工具.StarUML是一个开源项目 ...

  5. 【转发】查看Linux版本系统信息方法汇总

    Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然.   1.# uname -a   (Linux查看版本当前操作系统内核信息)   L ...

  6. Hibernate缓存机制 (2013-07-02 13:51:32)转载▼

    标签: java web hibernate 缓存 代码        分类: javaweb 缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访 ...

  7. AFNETWorking3.x实战教程

    上一篇文章介绍了优秀的第三方网络请求框架AFNETWorking2.0,本篇就通过一个实战例子来总结AFNetworking的使用. 本文参考http://www.raywenderlich.com/ ...

  8. zookeeper3.4.6的安装

    最近为了解决HDFS的单点故障的问题,采用了HA的方式是实现,并通过zookeeper来实现自动切换,既然需自动切换的话,那么必须要安装zookeeper,我选用的版本是3.4.6.下面详细介绍一下其 ...

  9. ZOJ 3747 - Attack on Titans (递推)

    题意:有三个兵种R,G,C,选取N个排成一列,要求G至少有M个连续的,R至多有K个连续的,问有多少种排列方式. 此题与UVa 10328 - Coin Toss非常相似,都是问某个字符连续出现的种数. ...

  10. JS 原型继承的几种方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...