在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. MariaDB 数据库系统概述(1)

    MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...

  2. java的基本数据类型--四类八种

    java的数据类型 1.分为基本数据类型和引用数据类型 基本数据类型的分类:整数型: byte  占用一个字节 范围-128-127 short 占用两个字节  -2^15~2^15-1 int    ...

  3. 转---移动端 h5开发相关内容总结——CSS篇

    作者:伯乐在线专栏作者 - zhiqiang21 如有好文章投稿,请点击 → 这里了解详情 如需转载,发送「转载」二字查看说明 1.移动端开发视窗口的添加 h5端开发下面这段话是必须配置的 meta ...

  4. webstorm无法显示左边文件夹目录的解决方法

    webstorm无法显示左边文件夹目录的解决方法 方法一 view-->Tool Windows-->Project 就可以显示或者关闭 方法二 1.删除webstorm的配置文件夹 2. ...

  5. Git使用、Git配置、Git提交代码、Git上传

    非教程,只是自己的一个简单笔记.建议没有入门的朋友,直接看git的官方help文档: https://help.github.com/articles/set-up-git 1.注册一个git账号,超 ...

  6. C语言写了一个socket client端,适合windows和linux,用GCC编译运行通过

    ////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o c1 c1 ...

  7. 五、CLR加载程序集代码时,JIT编译器对性能的产生的影响

    1.CLR首次加载代码造成的性能损失 四.CLR执行程序集中代码介绍了CLR在首次执行一个类的时,会初始化一个内部结构,然后当目标方法被首次调用时,JITComplier函数(JIT编译器)会验证IL ...

  8. Zookeeper--0200--安装与集群搭建、常用命令、客户端工具

    看这里,http://www.cnblogs.com/lihaoyang/p/8358153.html 1,先使用可视化客户端软件 ZooInspector 连接上集群中的一个节点,看下zk的结构: ...

  9. Java 死锁优化

    死锁示例1 public class SyncThread implements Runnable{ private Object obj1; private Object obj2; public ...

  10. hexo 静态页面生成后页面打不开的问题

    我这里的原因是4000端口被占用了 *** hexo入门指南教程: 官方文档 用Hexo 3 搭建github blog 做一款hexo主题(进阶) 坑 1 要安装node和git 2 别忘了安装he ...