在linux中,用fork来创建一个子进程,该函数有如下特点:

1)执行一次,返回2次,它在父进程中的返回值是子进程的 PID,在子进程中的返回值是 0。子进程想要获得父进程的 PID 需要调用 getppid 函数。

2)生成的子进程会复制父进程一样的代码和数据

3)父子进程的全局变量和局部变量,有两份拷贝

4)子进程会继承父进程的环境状态

5)父进程会把当前执行程序的进度(即:程序运行到哪儿)也复制给子进程

/*================================================================
* Copyright (C) 2018 . All rights reserved.
*
* 文件名称:fork.c
* 创 建 者:ghostwu(吴华)
* 创建日期:2018年01月12日
* 描 述:fork基本使用
*
================================================================*/ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int count = ; int main(int argc, char *argv[])
{
pid_t pid; int var = ; printf( "----fork之前------,当前进程id=%d\n", getpid() ); pid = fork(); printf( "----fork之后------\n" ); if( pid < ) {
perror( "fork" );
exit( - );
}else if( pid == ) {
//子进程
var++;
count++;
}else {
sleep( );
} printf( "fork返回值pid=%d, 当前进程pid=%d, count=%d, var=%d\n", pid, getpid(), count, var );
return ;
}

上例,我们可以看出:

1)子进程并不会输出"fork之前“这段代码,因为子进程拷贝的是fork之后的代码

2)子进程对变量操作之后,对父进程的变量没有任何影响,他们是2个不同的副本

3)标准输出是行缓冲模式:遇到换行符时进行刷新、缓冲区满了的时候刷新、强制刷新(fflush);而标准输出(stdout)是行缓冲,因为涉及到终端设备;

把这个例子的输出方式,再改一下:

这里,你会发现,多了两个输出( "fork之前" ),因为,采用管道重定向输出之后,IO操作就变成了全缓冲模式,子进程产生的时候是会复制父进程的缓冲区的数据的,所以子进程刷新缓冲区的时候子进程也会将从父进程缓冲区中复制到的内容刷新出来。因此,在使用 fork产生子进程之前一定要使用 fflush(NULL) 刷新所有缓冲区!

/*================================================================
* Copyright (C) 2018 . All rights reserved.
*
* 文件名称:fork.c
* 创 建 者:ghostwu(吴华)
* 创建日期:2018年01月12日
* 描 述:fork基本使用
*
================================================================*/ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int count = ; int main(int argc, char *argv[])
{
pid_t pid; int var = ; printf( "----fork之前------,当前进程id=%d\n", getpid() ); fflush( NULL );
pid = fork(); printf( "----fork之后------\n" ); if( pid < ) {
perror( "fork" );
exit( - );
}else if( pid == ) {
//子进程
var++;
count++;
}else {
sleep( );
} printf( "fork返回值pid=%d, 当前进程pid=%d, count=%d, var=%d\n", pid, getpid(), count, var );
return ;
}

这个时候,就不会有两个("fork之前" ),因为fork生成子进程之前,已经把父进程缓冲区的数据刷新到内核缓冲区,不在标准IO的缓冲区

子进程如果比父进程先结束,那么子进程会变成僵尸进程。

因为:它们必须得等待父进程为其“收尸”才能彻底释放,如果父进程先结束了,那么这些子进程的父进程会变成 1 号 init 进程,当这些子进程运行结束时会变成僵尸进程,然后 1 号 init 进程就会及时为它们收尸

/*================================================================
* Copyright (C) 2018 . All rights reserved.
*
* 文件名称:fork3.c
* 创 建 者:ghostwu(吴华)
* 创建日期:2018年01月12日
* 描 述:
*
================================================================*/ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(int argc, char *argv[])
{
pid_t pid;
int i = ; for( i = ; i < ; i++ ) {
pid = fork();
if( pid < ) {
perror( "fork()" );
exit( - );
}else if( pid == ) {
printf( "[pid]=%d\n", getpid() );
exit( );
}
}
sleep( ); return ;
}

父进程如果比子进程先结束,那么子进程会变成孤儿进程

所有子进程的父进程都变成了 1 号 init 进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(int argc, char *argv[])
{
pid_t pid;
int i = ; for( i = ; i < ; i++ ) {
pid = fork();
if( pid < ) {
perror( "fork()" );
exit( - );
}else if( pid == ) {
sleep( );
printf( "[pid]=%d\n", getpid() );
exit( );
}
} return ;
}

linux系统编程:进程控制(fork)的更多相关文章

  1. Linux系统编程@进程通信(一)

    进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...

  2. linux系统编程-进程

    进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...

  3. Linux系统编程@进程管理(一)

    课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...

  4. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  5. [linux] C语言Linux系统编程进程基本概念

    1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...

  6. Linux系统编程-----进程fork()

    在开始之前,我们先来了解一些基本的概念: 1. 程序, 没有在运行的可执行文件 进程, 运行中的程序 2. 进程调度的方法: 按时间片轮转 先来先服务 短时间优先 按优先级别 3. 进程的状态: 就绪 ...

  7. Linux系统编程——进程替换:exec 函数族

    在 Windows 平台下,我们能够通过双击运行可运行程序,让这个可运行程序成为一个进程.而在 Linux 平台.我们能够通过 ./ 运行,让一个可运行程序成为一个进程. 可是.假设我们本来就执行着一 ...

  8. Linux系统编程—进程间同步

    我们知道,线程间同步有多种方式,比如:信号量.互斥量.读写锁,等等.那进程间如何实现同步呢?本文介绍两种方式:互斥量和文件锁. 互斥量mutex 我们已经知道了互斥量可以用于在线程间同步,但实际上,互 ...

  9. linux服务器开发二(系统编程)--进程相关

    进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...

  10. linux系统编程之进程(一)

    今天起,开始学习linux系统编程中的另一个新的知识点----进程,在学习进程之前,有很多关于进程的概念需要了解,但是,概念是很枯燥的,也是让人很容易迷糊的,所以,先抛开这些抽象的概念,以实际编码来熟 ...

随机推荐

  1. Spring Integration Zip不安全解压(CVE-2018-1261)漏洞复现

    不敢说分析,还是太菜了,多学习. 文章来源: 猎户安全实验室 存在漏洞的源码下载地址:https://github.com/spring-projects/spring-integration-ext ...

  2. [LeetCode] 反转整数

    题目: 给定一个 32 位有符号整数,将整数中的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注 ...

  3. iframe 自适应高度和宽度

    <iframe src="pay/index.aspx" marginheight="0" marginwidth="0" frame ...

  4. socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)

    通过socket实现两台FTP服务器指定目录下的文件转移,其中包含了基础了ftp文件列表显示.上传和下载.这里仅供学习用,需掌握的点有socket.ftp命令.文件流读取转换等 完整代码如下: Ftp ...

  5. WebForm——JS检测浏览器是否是IE浏览器

    function IEVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 && userAgen ...

  6. Linux CPU实时监控工具

    注:ubuntu需要安装sysstat: sudo apt install sysstat [root@testDb ~]# mpstat 1 10    ---显示操作系统内核版本 以及硬件配置   ...

  7. War文件部署

    其实,开始要求将源码压缩成War文件时,一头雾水! 公司项目要求做CAS SSO单点登录 也就是这玩意.... 其实war文件就是Java中web应用程序的打包.借用一个老兄的话,“当你一个web应用 ...

  8. GO入门——4. 数组、切片与map

    1. 数组 定义数组的格式:var [n],n>=0 数组长度也是类型的一部分,因此具有不同长度的数组为不同类型 注意区分指向数组的指针和指针数组 //数组的指针 a := [2]int{1, ...

  9. 【工具向01】——markdown 文本编辑语言相关

    markdown简介 Markdown是一种轻量级标记语言创始人为约翰·格鲁伯.它允许人们"使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML或HTML文档".这种语言吸 ...

  10. Hadoop2源码分析-Hadoop V2初识

    1.概述 在完成分析Hadoop2源码的准备工作后,我们进入到后续的源码学习阶段.本篇博客给大家分享,让大家对Hadoop V2有个初步认识,博客的目录内容如下所示: Hadoop的渊源 Hadoop ...