一、函数fork

#include<unistd.h>

pid_t  fork(void)                                                                    子进程返回0,父进程返回子进程ID,出错返回-1

fork函数被调用一次,返回两次。先返回父进程还是子进程是不确定的,取决于内核使用的调度算法。

子进程和父进程并不共享存储空间,而是共享正文段。因此,子进程对变量所做的改变并不影响父进程中该变量的值。

父进程和子进程共享同一个文件偏移量。fork之后处理fd的两种情况:

(1)父进程等待子进程完成,当子进程完成操作后,它们任一共享的fd的文件偏移量,已经更新,父进程可以接着子进程继续工作。

(2)父进程和子进程各自执行不同的程序段,fork之后,父进程和子进程各自关闭它们不需要使用的fd,这样就不会干扰对方使用的fd,否则产生的文件偏移量会共享给对方,由于是执行不同的程序段,所以会产生干扰。(常用于网络服务进程,Socket通信中的server)

父进程与子进程的区别如下:

v    fork的返回值不同

v    进程ID不同

v    两个进程的父进程ID不同

v    子进程的tms_utime、tms_stime、tms_cutime、tms_ustime、的值设置为0.

v    子进程不继承父进程设置的文件锁。

v    子进程的未处理闹钟被清除。

v    子进程的未处理信号集设置为空集。

标准fork用法示例:已备后续查看

#include "apue.h"

int             globvar = 6;            /* external variable in initialized data */
char buf[] = "a write to stdout\n"; int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid; var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork\n"); /* we don't flush stdout */ if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
globvar++; /* modify variables */
var++;
} else {
sleep(2); /* parent */
} printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar,
var);
exit(0);
}

二、函数vfork

与fork的区别:

(1).vfork也是创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为vfork的目的是让子进程立即exec一个启动例程,这样,它也就不会引用该地址空间。

(2).vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行,否则,会导致死锁。而fork之后父进程和子进程谁先执行是不确定的。

三、函数exit

进程的8种终止状态:

正常终止为:

(1).从main返回

(2).调用exit

(3)调用_exit或_Exit

(4)最后一个线程从其启动例程返回

(5)从最后一个线程调用pthread_exit

异常终止为:

(6)调用abort

(7)接到一个信号终止

(8)最后一个线程对取消请求做出响应

在任意一种情况下,该终止进程的父进程都能用wait或waitpid函数取得其终止状态。

有意思的两种情况:

(1).父亲先死:

如果父进程在子进程之前终止,那么这些子进程的父进程变为init进程,称这些子进程由init进程收养。(这里很有意思,就是说如果父亲在儿子之前死了,那么这些孩子都会被init这个孤儿收容所所认,都成了init的儿子。)

父进程30314 fork了子进程30315

kill -9 30314 我们杀死父亲之后,

果然,子进程被init进程收养,并在sleeping状态。

(2).儿子先死

如果子进程完全消失了,父进程在最终准备好检查子进程是否终止时是无法获取它的状态的,内核为每个终止子进程保存了一定量的信息,所以父进程调用wait或waitpid可以得到这些信息。在Unix中,如果父进程无法获取子进程的终止状态,那么这些子进程会变为僵死进程。(形象的说,如果父亲不负责任,他对自己儿子的死一无所知,那么这个孩子死不瞑目,变为僵死状态。)

这回我们还是先fork一个子进程,kill -9 30425 ,先杀死儿子,我们看到父进程还在后台运行,由于我们用kill -9属于“偷偷”杀死的儿子,父亲无法获取儿子的死讯,因此,儿子变为僵死进程。

此外,init被编写成无论何时只要有一个子进程终止,init就会调用一个wait函数取得其终止状态。防止在系统中塞满僵死进程。

Unix高级环境编程—进程控制(一)的更多相关文章

  1. UNIX高级环境编程1

    UNIX高级环境编程1 故宫角楼是很多摄影爱好者常去的地方,夕阳余辉下的故宫角楼平静而安详. 首先,了解一下进程的基本概念,进程在内存中布局和内容. 此外,还需要知道运行时是如何为动态数据结构(如链表 ...

  2. UNIX高级环境编程(14)文件IO - O_DIRECT和O_SYNC详解 < 海棠花溪 >

    春天来了,除了工作学习,大家也要注意锻炼身体,多出去运动运动.  上周末在元大都遗址公园海棠花溪拍的海棠花.   进入正题. O_DIRECT和O_SYNC是系统调用open的flag参数.通过指定o ...

  3. UNIX高级环境编程(11)进程控制(Process Control)- 进程快照,用户标识符,进程调度

    1 进程快照(Process Accounting) 当一个进程终止时,内核会为该进程保存一些数据,包括命令的小部分二进制数据.CPU time.启动时间.用户Id和组Id.这样的过程称为proces ...

  4. UNIX高级环境编程(8)进程环境(Process Environment)- 进程的启动和退出、内存布局、环境变量列表

    在学习进程控制相关知识之前,我们需要了解一个单进程的运行环境. 本章我们将了解一下的内容: 程序运行时,main函数是如何被调用的: 命令行参数是如何被传入到程序中的: 一个典型的内存布局是怎样的: ...

  5. Unix高级环境编程

    [07] Unix进程环境==================================1. 进程终止    atexit()函数注册终止处理程序.    exit()或return语句:    ...

  6. UNIX高级环境编程(9)进程控制(Process Control)- fork,vfork,僵尸进程,wait和waitpid

    本章包含内容有: 创建新进程 程序执行(program execution) 进程终止(process termination) 进程的各种ID   1 进程标识符(Process Identifie ...

  7. UNIX高级环境编程(10)进程控制(Process Control)- 竞态条件,exec函数,解释器文件和system函数

    本篇主要介绍一下几个内容: 竞态条件(race condition) exec系函数 解释器文件    1 竞态条件(Race Condition) 竞态条件:当多个进程共同操作一个数据,并且结果依赖 ...

  8. UNIX高级环境编程(15)进程和内存分配 < 故宫角楼 >

    故宫角楼是很多摄影爱好者常去的地方,夕阳余辉下的故宫角楼平静而安详.   首先,了解一下进程的基本概念,进程在内存中布局和内容. 此外,还需要知道运行时是如何为动态数据结构(如链表和二叉树)分配额外内 ...

  9. UNIX高级环境编程(12)进程关联(Process Relationships)- 终端登录过程 ,进程组,Session

    在前面的章节我们了解到,进程之间是有关联的: 每个进程都有一个父进程: 子进程退出时,父进程可以感知并且获取子进程的退出状态. 本章我们将了解: 进程组的更多细节: sessions的内容: logi ...

随机推荐

  1. 洛谷 P2863 [USACO06JAN]牛的舞会The Cow Prom-强连通分量(Tarjan)

    本来分好组之后,就确定好了每个人要学什么,我去学数据结构啊. 因为前一段时间遇到一道题是用Lca写的,不会,就去学. 然后发现Lca分为在线算法和离线算法,在线算法有含RMQ的ST算法,前面的博客也写 ...

  2. CSU 1779: 错误的算法【矩阵/模拟】

    Description 有道题目是这样的: 输入一个 n 行 m 列网格,找一个格子,使得它所在的行和列中所有格子的数之和最大.如果答 案不唯一,输出任意解即可.比如,在下面的例子中,最优解是(1,3 ...

  3. 10.1综合强化刷题 Day3 afternoon

    竞赛时间:????年??月??日??:??-??:?? 题目名称 a b c 名称 a b c 输入 a.in b.in c.in 输出 a.out b.out c.out 每个测试点时限 1s 1s ...

  4. Codeforces 869 C The Intriguing Obsession

    题目描述 — This is not playing but duty as allies of justice, Nii-chan! — Not allies but justice itself, ...

  5. 开启KindEditor代码高亮功能

    KindEditor4.0 开始支持插入代码功能!!!如何使用插入代码功能实现前段页面代码高亮显示和后台代码维护显示!!! 1. 需要高亮显示代码的前台页面需要引用相应的css样式和js文件 < ...

  6. jquery dataTable 获取某行数据

    DataTable API table.row(rowSelector [,modifier]) 注table是dataTable的对象 该方法有两个默认参数 第一个是选择器 第二个是可选的 请注意, ...

  7. CoreData: 如何预载/导入已有的数据

    原文地址:CoreData: 如何预载/导入已有的数据作者:出其东门 在系列教程一中,我们为对象建立了可视化数据模型,运行了快速肮脏测试并勾在一个表视图(table view)中来显示.而在这个教程, ...

  8. VS2010 MFC中 静态编译设置方法

    问题:VS2010 c++编写的程序在别人的机子运行不了,缺少mfc100u.dll xxx100d.dll等 解决方法:1.将这些dll打包,和应用程序一起发布;2.采用MFC静态编译; 静态编译: ...

  9. 【C语言 C++】简单keywordRegister,Const,Static,Volatile,typedef,Define的理解

    Register 用register声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器 中.但对32位编译器不起作用.当global optimizations(全局优化)开的时候,它会 ...

  10. AutoCAD如何设置A0A1图纸

    可以从网上下载相应的图纸模板,下载之后可以发现有相应的文字和模板文件   随后我们新建并找到这个dwt文件模板(比如要做一个A1的模板)   随后即可发现模板的样式,包括每种颜色的粗细,颜色和明细栏等 ...