在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. 详述MSSQL服务在渗透测试中的利用(上篇)

    前言: 致力于复现最实用的漏洞利用过程. 本文将带领大家学习以下内容: 学习使用`xp_cmdshell`扩展存储过程 学习调用`wscript.shell` 学习MSSQL写文件 学习沙盘模式提权 ...

  2. Influxdb简介与安装

    InfluxDB 是用Go语言编写的一个开源分布式时序.事件和指标数据库,无需外部依赖,类似的数据库有Elasticsearch.Graphite等 功能特色 基于时间序列,支持与时间有关的相关函数( ...

  3. 6_文件IO

    1. 基本文件读取         readline(),readlines(),write(),writelines()         f.read(size),指定读取文件的字节数,需要注意的是 ...

  4. 【转载】InstallShield 生成安装日志

    msiexec.exe /p "C:\Documents and Settings\qa\Desktop\8.3 Patch.msp" /l*v c:\log85gold.log ...

  5. IIS 站点部署多级域名

    当站点的规模达到一定程度,往往会对业务进行拆分,部署到一台服务器的不同站点,,而一个域名(顶级域名)只能绑定一个站点(核心站点),这个时候就通过给顶级域名创建子域名的方式(理论上一个顶级域名可以绑定5 ...

  6. donet core 应用 部署到CentOS

    创建应用 新建一个Asp.net core Web API 应用 在program里指定监听端口 public static IWebHost BuildWebHost(string[] args) ...

  7. Android之密码的显示与隐藏

    很多应用都是显示与隐藏密码的功能. 之前的项目都没这个功能要求,也没有专门研究这个.最近项目有加这个功能,我这里也刚好整理一下. 我的思路是设置EditText的InputType.代码如下: if ...

  8. Ajax(javascript)案例

    一.注册案例(Get方式) 1.前台 <%@ page language="java" import="java.util.*" pageEncoding ...

  9. CentOS 6.9上inotify-tools 安装及使用方法

    文章目录 [隐藏] 一.检查系统内核版本 三.下载安装(下载有点慢) 四.查看inotify默认参数 五.修改inotify参数 六.创建实时监控脚本 (file 里面放的需要监听的目录) 七:实例操 ...

  10. 30-hadoop-hbase-安装squirrel工具

    如果您的工作要求您在一天之中连接许多不同的数据库 (oracle.DB2.mysql.postgresql.Sql Server等等),或者你经常需要在多个不同种类的数据库之间进行数导入导出.那么SQ ...