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系统编程中的另一个新的知识点----进程,在学习进程之前,有很多关于进程的概念需要了解,但是,概念是很枯燥的,也是让人很容易迷糊的,所以,先抛开这些抽象的概念,以实际编码来熟 ...
随机推荐
- urllib2 的get请求与post请求
urllib2默认只支持HTTP/HTTPS的GET和POST方法 urllib.urlencode() urllib和urllib2都是接受URL请求的相关参数,但是提供了不同的功能.两个最显著的不 ...
- 基本数据类型补充 set集合 深浅拷贝
一.基本数据类型补充 1,关于int和str在之前的学习中已经介绍了80%以上了,现在再补充一个字符串的基本操作: li = ['李嘉诚','何炅','海峰','刘嘉玲'] s = "_&q ...
- 前端开发者不得不知的ES6十大特性
前端开发者不得不知的ES6十大特性 转载 作者:AlloyTeam 链接:http://www.alloyteam.com/2016/03/es6-front-end-developers-will- ...
- Swift 里 Set(二)概览
类图  Set 是一个结构体,持有另一个结构体_Variant. 最终所有的元素存储在一个叫做__RawSetStorage的类里. 内存布局  结构体分配在栈上,和__RawSetStorage ...
- defer 的常用场景
将panic的转化为error类型值,并将其作为函数值返回给调用方 package main import "fmt" func divide(a, b int) (res int ...
- Oracle 查看当前数据库版本的方法
常用的有三种方法: 方法一:v$version SQL> select * from v$version; BANNER ---------------------------------- ...
- (转)python高级FTP
原文地址:http://www.itnose.net/detail/6754889.html高级FTP服务器1. 用户加密认证2. 多用户同时登陆3. 每个用户有自己的家目录且只能访问自己的家目录4. ...
- Java 内存分配及垃圾回收机制初探
一.运行时内存分配 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则 ...
- jieba分词(1)
近几天在做自然语言处理,看了一篇论文:面向知识库的中文自然语言问句的语义理解,里面提到了中文的分词,大家都知道对于英文的分词,NLTK有很好的支持,但是NLTK对于中文的分词并不是很好(其实也没有怎么 ...
- 大整数相加 a+b 的c语言实现
终于来到我所期盼的高精度整数相加的题目了.这个题很经典,也算是一个很好的算法入门题吧. 如果是java的话,系统类库已经内置了BigInteger类,直接调用就可以很轻易地解决了.但是学习c的编写也是 ...