linux系统编程:进程控制(fork)
在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)的更多相关文章
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- linux系统编程-进程
进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- Linux系统编程@进程管理(二)
1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...
- [linux] C语言Linux系统编程进程基本概念
1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...
- Linux系统编程-----进程fork()
在开始之前,我们先来了解一些基本的概念: 1. 程序, 没有在运行的可执行文件 进程, 运行中的程序 2. 进程调度的方法: 按时间片轮转 先来先服务 短时间优先 按优先级别 3. 进程的状态: 就绪 ...
- Linux系统编程——进程替换:exec 函数族
在 Windows 平台下,我们能够通过双击运行可运行程序,让这个可运行程序成为一个进程.而在 Linux 平台.我们能够通过 ./ 运行,让一个可运行程序成为一个进程. 可是.假设我们本来就执行着一 ...
- Linux系统编程—进程间同步
我们知道,线程间同步有多种方式,比如:信号量.互斥量.读写锁,等等.那进程间如何实现同步呢?本文介绍两种方式:互斥量和文件锁. 互斥量mutex 我们已经知道了互斥量可以用于在线程间同步,但实际上,互 ...
- linux服务器开发二(系统编程)--进程相关
进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...
- linux系统编程之进程(一)
今天起,开始学习linux系统编程中的另一个新的知识点----进程,在学习进程之前,有很多关于进程的概念需要了解,但是,概念是很枯燥的,也是让人很容易迷糊的,所以,先抛开这些抽象的概念,以实际编码来熟 ...
随机推荐
- HTML引入JS文件
浏览器解析HTML文件时,先判断script 标签中是否有src属性,有则执行指定路径下的JS文件,没有则执行script标签中的js脚本. 1. HTML内嵌JS head里面添加script元素, ...
- Javascript如何避免连续调用中取到不存在的属性而导致报TypeError错?
背景: 在最近的 NODEJS 项目中,涉及到数据库的查询,回调函数里返回了查询结果,我这样做处理然后返回给前端: return results.collect_coupon[0].count 但是这 ...
- js缓存问题,修改js后代码不生效
问题描述 最近在上线新版本项目的时候,发现有的用户的操作还是调用的老版本JS里面的内容,这样就造成原来新的JS里面加上的限制不能限制用户的操作,从而导致用户可以重复操作. 问题产生原因 如果在用户之前 ...
- 【xsy2194】Philosopher set+线段树合并
题目大意:给你一个长度为$n$的序列,有$m$次操作,每次操作是以下两种之一: 对某个区间内的数按照升序/降序排序,询问某个区间内数的积在十进制下首位数字是多少. 数据范围:$n,m≤2\times ...
- odoo开发笔记 -- 安装Backend debranding去除odoo信息模块后 隐藏开发者模式
Backend debranding 找到如下文件,将相关灰色代码注释掉. <?xml version="1.0" encoding="UTF-8"?&g ...
- linux 下 etc常用配置信息
这些都是比较有实用性的系统配置,收藏下,以备不时之需!以下是etc下重要配置文件解释: 1./etc/hosts #文件格式: IPaddress hostname aliases #文件功能: 提 ...
- Linux命令对应的英文全称
su:Swith user 切换用户,切换到root用户cat: Concatenate 串联uname: Unix name 系统名称df: Disk free 空余硬盘du: Disk u ...
- c++实现二叉树层序、前序创建二叉树,递归非递归实现二叉树遍历
#include <iostream> #include <cstdio> #include <stdio.h> #include <string> # ...
- Choose GitLab for your next open source project
原文:https://b.agilob.net/choose-gitlab-for-your-next-project/ GitLab.com is a competitor of GIthub. I ...
- 全网最详细的实用的搜索工具【堪称比Everything要好】Listary软件的下载与安装(图文详解)
不多说,直接上干货! 但是呢,作为博主的我而言,一般不用免费版,喜欢用专业版,具体原因,你懂得. 下载,得到 需要破解安装包的,进 对应本平台的讨论和答疑QQ群:大数据和人工智能躺过的坑(总群)(16 ...