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. 多测师讲解自动化测试 _RF自定义关键字_高级讲师肖sir

    RF自定义关键字 在rf中叫关键字 在python中就叫做函数 或实例方法 我们自己可以写自定义关键字 自己创建一个库===库里面去创建模块===模块里面创建类和实例方法==>rf导入和引用 库 ...

  2. 【UER #1】DZY Loves Graph

    UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...

  3. lumen-ioc容器测试 (5)

    lumen-ioc容器测试 (1) lumen-ioc容器测试 (2) lumen-ioc容器测试 (3) lumen-ioc容器测试 (4) lumen-ioc容器测试 (5) lumen-ioc容 ...

  4. linux(centos8):阿里云ecs配置smtps发邮件(解决不能通过25端口发邮件问题)

    一,2016年9月后购买的阿里云ecs不再支持通过25端口发送邮件 官方的建议是使用465端口 465端口(SMTPS): 465端口是为SMTPS(SMTP-over-SSL)协议服务开放的 它是S ...

  5. 在 Istio 中实现 Redis 集群的数据分片、读写分离和流量镜像

    Redis 是一个高性能的 key-value 存储系统,被广泛用于微服务架构中.如果我们想要使用 Redis 集群模式提供的高级特性,则需要对客户端代码进行改动,这带来了应用升级和维护的一些困难.利 ...

  6. hdu6115 Factory (LCA + 倍增)

    Factory Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total ...

  7. shell中将带分隔符的字符串转为数组

    shell中将字符串列表转换成数组,需要将数组用括号来表示,元素用"空格"符号分割开,格式如下: array_name=(value1 ... valuen) 使用内置的分割符IF ...

  8. Monitor Ctrl-Break线程,有点坑

    Monitor Ctrl-Break线程这个在idea中特有的线程,你了解吗?这线程可能会在你调试的时候给你带来谜一样的结果,为什么呢?请看下面的例子: 首先我们先复习一下多线程的状态(因为这个问题是 ...

  9. 熔断原理与实现Golang版

    在微服务中服务间依赖非常常见,比如评论服务依赖审核服务而审核服务又依赖反垃圾服务,当评论服务调用审核服务时,审核服务又调用反垃圾服务,而这时反垃圾服务超时了,由于审核服务依赖反垃圾服务,反垃圾服务超时 ...

  10. 什么PO模式?

    PO模式PO是Page Object的缩写,PO模式是自动化测试项目开发实践的最佳设计模式之一.核心思想是通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化, 只需要调整页面元素封 ...