UNIXC002 进程创建,终止,遗言函数
进程的基础知识
1. 程序和进程
2. 查看进程信息
3. 进程的状态
进程的创建
1. fork 创建一个子进程
- 通俗的讲,这个函数调用一次但可能"返回两次"。
- 父进程中调用fork,在创建子进程成功的情况下,会在父进程中返回子进程pid,并会在子进程中返回0。
- 如果没有创建成功,只会在父进程中返回-1。
2. 代码示例
t_stdio.h
#ifndef T_STDIO_H_
#define T_STDIO_H_
#include <stdio.h>
#define E_MSG(STRING, VAL) do{perror(STRING); return(VAL);}while(0)
#endif
fork.c
#include "t_stdio.h"
#include <unistd.h>int main(void){pid_t pid = fork();if(pid == -1)E_MSG("fork", -1);if(pid == 0){// 在子进程中执行的代码printf("child process ...\n");} else {// 在父进程中执行的代码printf("parent process ...\n");}// 父子进程都会执行的代码printf("parent and child process ...\n");return 0;
}
# 有可能先打印 parent process..., 也有可能先打印 child process ...
# 取决与系统的调度, 并且父进程是不会等子进程的,除非用到wait等系统调用
$ ./a.out
parent process ...
parent and child process ...
child process ...
parent and child process ...
3. 父子进程共享父进程PCB
- 子进程和父进程共享父进程的PCB,节省了资源开销
- 上图是父子进程的代码段,一模一样,因为子进程和父进程用的映像(代码段,数据段, 栈段, 堆等)是同一个(只有写时才复制相应的部分)。只不过根据fork返回值的不同,父子进程执行了不同代码而已。
- 左图是父进程的代码段,当父进程中fork函数执行完,如果返回值是-1时,那么子进程不会存在了(右图不会出现)。
- 如果父进程fork函数成功了,返回值就是子进程的pid。右图出现,子进程和父进程共用一个映像。 父进程继续会执行 printf(“parent process …\n”); 然后继续执行 printf(“parent and child process …\n”);
- 子进程中的fork函数返回值是0, 子进程会执行 printf(“child process …\n”); 和 printf(“parent and child process …\n”);
进程的终止
1. return 和 exit(3) 的区别
- 0377 是8进制,转成2进制就是11 111 111,exit 会将参数的值转为2进制,然后和 11 111 111做与运算(只要低八位),然后转为10进制返回给父进程
- ./a.out 创建的进程的父进程就是当前这个 bash
- echo $? 显示当前命令的返回值
2. 代码示例
exit.c
#include <stdlib.h>
#include <stdio.h>
int main(void){// getchar();exit(3);return 0;
}
// $ gcc exit.c
// $ ./a.out
// $ echo $?
// 3#include <stdlib.h>
#include <stdio.h>
int main(void){// -1的二进制表示方式(低8位)是11 111 11exit(-1); //return -1; 结果好像也是255return 0;
}
// $ gcc exit.c
// $ ./a.out
// $ echo $?
// 255
遗言函数
1. 什么是遗言函数
2. 向进程注册遗言函数 atexit(3)
- atexit(3)的参数变量是一个函数指针类型的
- 子进程继承父进程的遗言函数,因为父子进程共享同一个映像,所以父进程能执行的遗言函数,子进程终止时也能执行。
atexit.c
#include <stdlib.h>
#include "t_stdio.h"
#include <unistd.h>
// 进程的遗言函数
void bye(void){printf("bye...\n");
}
void goodbye(void){printf("goodbye...\n");
}
int main(void){// 向进程注册遗言函数atexit(bye);atexit(goodbye);// 验证子进程继承父进程的遗言函数// 创建子进程需要在注册之后,不然无法继承父进程的遗言函数pid_t pid=fork();if(pid == -1)E_MSG("fork", -1);return 0;
}
# 观察输出发现,遗言函数的注册顺序和调用顺序相反
$ ./a.out
goodbye...
bye...
goodbye...
bye...
3. 向进程注册遗言函数 on_exit(3)
#include <stdlib.h>
#include "t_stdio.h"
#include <unistd.h>
// 遗言函数的定义
// return 或 exit后面的参数(没有与0377做与运算)会传递给n
void bye(int n, void *arg){printf("bye...%d...%s\n", n, (char *)arg);
}int main(void){// 向进程注册遗言函数, 一样,调用顺序和注册顺序相反on_exit(bye, "hello");// 验证子进程继承父进程的遗言函数// 创建子进程需要在注册之后,不然无法继承父进程的遗言函数pid_t pid=fork();if(pid == -1)E_MSG("fork", -1);exit(-1);// return -1;
}
$ ./a.out
bye...-1...hello
bye...-1...hello
UNIXC002 进程创建,终止,遗言函数相关推荐
- 进程创建-终止-等待-替换
文章目录 进程创建 进程终止 进程等待 进程替换 进程创建 意义: 进程运行时常会出现崩溃,为了避免父进程出现奔溃,则会创建子进程去代替父进程处理事务,即使崩溃并不会影响到父进程的正常运行,再创建一个 ...
- 【Linux】进程控制 —— 进程创建/终止/等待
目录 一.进程创建 1.fork创建子进程,操作系统做了什么? 2.fork的用法以及失败的原因 二.进程终止 1.三种退出情况 2.main函数为什么一般情况下都要return 0 3.进程的退出码 ...
- Linux系统编程之进程控制(进程创建,fork函数,进程中止,进程等待,程序替换)
进程创建 fork()------复制,返回值,写时复制 vfork()创建子进程-子进程与父进程共用同一块虚拟地址空间, 为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出或者进行程序 ...
- c语言fork函数fpid初始值,进程创建,fork()函数讲解
一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也 就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同 ...
- 进程控制(进程创建与终止 | 进程等待 | 程序替换)
文章目录 一.进程创建 1. fork函数 2. fork创建进程 3. 写时拷贝 二.进程终止 1. 进程退出有三种情况 2. 常见进程终止方法 三.进程等待 背景(必要性) 1. 进程等待的方法 ...
- 【Linux 内核】进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )
文章目录 一.进程状态 二.进程创建 三.进程终止 ( 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 ) 一.进程状态 Linux 进 ...
- 从创建进程到进入 main 函数,发生了什么?
作者 | 轩辕之风O 来源 | 编程技术宇宙(ID:xuanyuancoding) 头图 | CSDN 下载自东方IC 前几天,读者群里有小伙伴提问:从进程创建后,到底是怎么进入我写的 main 函 ...
- Linux 进程控制 :进程创建,进程终止,进程等待,程序替换
进程创建 进程终止 进程等待 程序替换 进程创建 fork函数 创建一个子进程,父子进程代码共享,数据独有 #include <unistd.h> pid_t fork(void); 返回 ...
- 模拟进程创建、终止、阻塞、唤醒原语_操作系统第二章--进程的描述与控制
操作系统第二章--进程的描述与控制 前趋图和程序执行 前趋图 前趋图是一个有向无循环图DAG,用来描述进程之间执行的前后关系 初始结点:没有前趋的结点 终止结点:没有后继的结点 重量:表示该结点所含有 ...
最新文章
- Datawhale来杭电啦!
- linux nohup 英文全称 no hang up(
- python官方网站地址-index
- SpringBoot - 构建监控体系02_定义度量指标和 Actuator 端点
- 07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存
- 【库】/lib64/libc.so.6: version `GLIBC_2.14' not found问题
- mysql_connect报告”No such file or directory”错误的解决方法
- 2018-2019-2 20175320实验三《敏捷开发与XP实践》实验报告
- Python之 continue继续循环
- 使用 DateTimePicker 控件显示和选择时间
- 麦克纳姆轮全向移动机器人运动学模型应用
- clover更新驱动 后不能开机_黑苹果笔记本电池模式下省电驱动,延长笔记本续航...
- 【BZOJ4818】序列计数(动态规划,生成函数)
- 【codeforces 534B】Covered Path
- python 自动交易_Python自动化交易入门
- Matlab中textscan函数用法
- 求职必看~10分钟读懂国企、事业单位和公务员的区别
- namesilo域名注册教程
- Python3 Mac剪切板存取内容-xerox
- CLIP:从自然语言监督中学习可迁移的视觉模型
热门文章
- 多云管理平台发展的几个阶段
- 游戏开发小结——通过射线投射来创建子弹孔
- ROS功能包在线把速腾聚创点云格式转为velodyne点云格式
- 狂风测试大师 2003 下载
- java初学者快捷施法_新手JAVA程序员学习随笔--快捷键(Mac)(一)
- angular-1.2.32路由控制写法与《SPA设计与架构》写法的部分区别
- 支原体检测丨艾美捷支原体检测试剂盒解决方案
- 春计算机试题答案,2006春计算机专业试题答案(A卷).doc
- android:ellipsize = marquee 跑马灯,TextView设置android:ellipsize=marquee不滚动
- Mac使用鼠标滚轮方向与Win相反的解决办法