fork函数拓展
2024-08-27 12:11:13
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 }
最新文章
- 在VMware8.0.4安装centos6.3出现蓝屏,显示“anaconda: Fatal IO error 104 (Connection reset by peer) on X server :1.0. install exited abnormally [1/1]”?
- ABAP屏幕设计
- asp.net 分页-利用后台直接生成html分页
- [CF355C]Vasya and Robot(思维,贪心)
- 【Implement strStr() 】cpp
- LineNumberReader类的使用
- 显示 mac 隐藏文件
- 聚类算法初探(四)K-means
- java logger级别
- Cyclomatic complexity
- HTML5 DTD
- HttpGet()和HttpPost()
- Spring学习笔记(二)之装配Bean
- sublime 安装package control
- Uva - 804 - Petri Net Simulation
- Quick Select算法
- 傻瓜学编程之block_1
- CentOS7 下源代码安装php7
- 关于maven:调整你的maven的jdk版本为 xxxx
- 单页面vue引入百度统计的使用方法!
热门文章
- 多测师讲解_肖sir _rf报错归纳(1):
- Rust之路(0)
- day60 Pyhton 框架Django 03
- RLP序列化算法
- pytest文档41-参数化 ids 用例描述为中文时控制台输出unicode编码问题(pytest_collection_modifyitems)
- <;二分查找+双指针+前缀和>;解决子数组和排序后的区间和
- 【不知道怎么分类】NOIP2016 蚯蚓
- jenkins:配置密钥时报错的解决:Failed to add SSH key. Message invalid privatekey(Jenkins 2.257)
- JAVA代码实现抖音短视频去水印功能
- 如何用vue实现一个矩形标记区域 rectangle marker