1、fork之后父子进程共享文件:文件引用计数的值改变,共享偏移。

在下面的例子中test.txt为parentchil。如果子进程没有睡眠,两个进程交叉执行,内容不可预测。

 1 #include<unistd.h>
2 #include<sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
9 #include<signal.h>
10 #define ERR_EXIT(m)\
11 do\
12 {\
13 perror(m);\
14 exit(EXIT_FAILURE);\
15 }while(0) //宏要求一条语句
16
17 int main()
18 {
19 signal(SIGCHLD,SIG_IGN);//避免僵死进程。父进程忽略子进程退出信号SIGCHLD
20 printf("before fork pid=%d\n",getpid());
21 int fd;
22 fd=open("test.txt",O_WRONLY);
23 if(fd==-1)
24 ERR_EXIT("open error");
25
26 pid_t pid;
27 pid=fork();
28 if(pid==-1)
29 ERR_EXIT("fork error");
30 if(pid>0)
31 {
32 printf("parent\n");
33 write(fd,"parent",6);
34 }
35
36 else if(pid==0)
37 {
38 sleep(1);
39 printf("child\n");
40 write(fd,"child",5);//偏移6,child在parent之后。
41 }
42
43 return 0;
44 }

2、fork与vfork:

  在fork还没有实现copy on write之前,UNIX设计者很关心fork之后立刻执行exec所造成的地址空间浪费,所以引入了vfork系统调用。vfork有个限制,子进程必须立刻
执行_exit或者exec函数。即使fork实现了copy on write,效率也没有vfork高,但是我们不推荐使用vfork,因为几乎每一个vfork的实现,都或多或少存在一定的问题。

vfork+exec:创建一个进程+exec vfork不会复制父进程地址空间,共享地址空间,直接替换进程,大大提高了效率。

 1 #include<unistd.h>
2 #include<sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
9 #include<signal.h>
10 #define ERR_EXIT(m)\
11 do\
12 {\
13 perror(m);\
14 exit(EXIT_FAILURE);\
15 }while(0) //宏要求一条语句
16 int gval=100;
17 int main()
18 {
19 signal(SIGCHLD,SIG_IGN);//避免僵死进程
20 printf("before fork pid=%d\n",getpid());
21
22 pid_t pid;
23 //pid=fork();//copy on write机制。数据改变时,子进程才拷贝。gval=100(p),gval=101(child)
24 pid=vfork();//gval=101(p) gval=101(c)在exec之前子进程是没有独立的地址空间的。且会有一个段错误vfork有个限制,子进程必须立刻执行_exit或者exec函数。
25 if(pid==-1)
26 ERR_EXIT("fork error");
27 if(pid>0)
28 {
29 sleep(1);
30 printf("parent,gval=%d\n",gval);//100
31 }
32
33 else if(pid==0)
34 {
35 gval++;
36 printf("child,gval=%d\n",gval);//101
37 _exit(0);//如果没有会有段错误。
38 }
39
40 return 0;
41 }

3、exit与_exit:

a、_exit是一个系统调用,exit是一个C库函数。

b、调用_exit直接陷入内核,进程终止;调用exit会先调用终止处理程序(终止处理程序是程序结束时调用的代码段,需要安装),然后清除I/O缓冲,接下来和_exit一样的操作。

4、atexit:

atexit可以注册终止处理程序,ANSI C规定最多只能注册32个终止处理程序。终止处理程序的调用与注册相反。

#include <stdlib.h>
int atexit(void (*function)(void));

 1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<stdlib.h>
4 #include<stdio.h>
5 #include<errno.h>
6 #define ERR_EXIT(m)\
7 do\
8 {\
9 perror(m);\
10 exit(EXIT_FAILURE);\
11 }while(0) //宏要求一条语句
12 void my_exit1(void)
13 {
14 printf("my exit1...\n");
15 }
16 void my_exit2(void)
17 {
18 printf("my exit2...\n");
19 }
20 int main()
21 {
22
23 atexit(my_exit1);
24 atexit(my_exit2);
25 exit(0);
26 //my exit2...
27 //my exit1...
28 }

fork函数拓展的更多相关文章

  1. Linux C 中 fork() 函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork() 函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同 ...

  2. 进程间通信--fork函数

    #include <unistd.h> pid_t fork(void); fork() creates a new process by duplicating the calling ...

  3. Fork函数初识

    fork函数用于创建子进程,典型的调用一次,返回两次的函数.其中调用进程返回子进程的PID,而子进程则返回0.但是两个进程的执行顺序是不定的. fork函数调用完成以后父进程的虚拟存储空间被拷贝给了子 ...

  4. fork()函数详解

    原文链接:http://blog.csdn.net/jason314/article/details/5640969  一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函 ...

  5. fork函数

    在Unix/Linux中用fork函数创建一个新的进程.进程是由当前已有进程调用fork函数创建,分叉的进程叫子进程,创建者叫父进程.该函数的特点是调用一次,返回两次,一次是在父进程,一次是在子进程. ...

  6. Linux—fork函数学习笔记

    fork()函数 在赋值语句pid = fork();之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的代码部分完全相同.> 两个进程中,原先就存在的那个被 ...

  7. linux fork函数与vfork函数,exit,_exit区别

    man vfork: NAME vfork - create a child process and block parent SYNOPSIS #include <sys/types.h> ...

  8. fork()函数

    现代操作系统提供的三种构造并发程序的方法: •进程 一个进程实体包括:代码段,数据段, 进程控制块 fork()函数:通过系统调用创建一个与原来一模一样的子线程,[用来处理请求信号,而父进程继续一直处 ...

  9. 进程控制之fork函数

    一个现有进程可以调用fork函数创建一个新进程. #include <unistd.h> pid_t fork( void ); 返回值:子进程中返回0,父进程中返回子进程ID,出错返回- ...

随机推荐

  1. 网络最大流Dinic

    1.什么是网络最大流 形象的来说,网络最大流其实就是这样一个生活化的问题:现在有一个由许多水管组成的水流系统,每一根管道都有自己的最大通过水流限制(流量),超过这个限制水管会爆(你麻麻就会来找你喝茶q ...

  2. Linux显示系统信息sh脚本

    #!/bin/bash # #******************************************************************** #Author: wangxia ...

  3. C++ std::thread 多线程中的异常处理

    环境: VS2019 包含头文件: #include <iostream>#include<thread>#include<exception> 线程函数采用try ...

  4. linux centos8 安装dokcker并启动coreapi

    粘的个人笔记,格式有点乱.勿在意 core api程序包 发布直接部署包: 链接:https://pan.baidu.com/s/1zZe9H1Fevf7DdzfF-MJb9w 提取码:t0ai 源码 ...

  5. docker是个啥?

    docker 第一问:什么是容器 容器就是在一个隔离的环境中运行的一个进程.注意关键词,隔离和进程.如果进程停止,那么容器就销毁.因为具有隔离的特点,所以每个容器都拥有自己的文件系统:包括IP地址.主 ...

  6. js 值类型与引用类型

    说明之前先提一个提问题,看一下你是怎么理解的 1. 值类型 简单的数据类型,存放在栈中 var num = 100; var num2 = num; num += 100; console.log(n ...

  7. CTF-misc:老板,再来几道misc玩玩

    [BJDCTF 2nd]最简单的misc-y1ng 得到一个图片,提示格式损坏,修补一下文件头 然后得到一张图片 直接python16进制转字符串 >>> string = &quo ...

  8. Luogu P3602 Koishi Loves Segments

    传送门 题解 既然是选取区间,没说顺序 肯定先排遍序 都是套路 那么按什么排序呢??? 为了方便处理 我们把区间按左端点从小到大排序 把关键点也按从小到大排序 假设当扫到 \(i\) 点时,i 点之前 ...

  9. GPRS DTU设备常见的问题分析

    在GPRS DTU设备使用的过程中,经常会遇到各种各样的问题,今天就为大家来分析一下在GPRS DTU设备使用时会遇到的一些问题. 1.GPRS模块设置 a.检查串口参数是否与GPRS模块的工作参数一 ...

  10. 机器学习 第5篇:knn回归

    基于最邻近算法的分类,本质上是对离散的数据标签进行预测,实际上,最邻近算法也可以用于对连续的数据标签进行预测,这种方法叫做基于最邻近数据的回归,预测的值(即数据的标签)是连续值,通过计算数据点最临近数 ...