进程的基础知识

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 进程创建,终止,遗言函数相关推荐

  1. 进程创建-终止-等待-替换

    文章目录 进程创建 进程终止 进程等待 进程替换 进程创建 意义: 进程运行时常会出现崩溃,为了避免父进程出现奔溃,则会创建子进程去代替父进程处理事务,即使崩溃并不会影响到父进程的正常运行,再创建一个 ...

  2. 【Linux】进程控制 —— 进程创建/终止/等待

    目录 一.进程创建 1.fork创建子进程,操作系统做了什么? 2.fork的用法以及失败的原因 二.进程终止 1.三种退出情况 2.main函数为什么一般情况下都要return 0 3.进程的退出码 ...

  3. Linux系统编程之进程控制(进程创建,fork函数,进程中止,进程等待,程序替换)

    进程创建 fork()------复制,返回值,写时复制 vfork()创建子进程-子进程与父进程共用同一块虚拟地址空间, 为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出或者进行程序 ...

  4. c语言fork函数fpid初始值,进程创建,fork()函数讲解

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

  5. 进程控制(进程创建与终止 | 进程等待 | 程序替换)

    文章目录 一.进程创建 1. fork函数 2. fork创建进程 3. 写时拷贝 二.进程终止 1. 进程退出有三种情况 2. 常见进程终止方法 三.进程等待 背景(必要性) 1. 进程等待的方法 ...

  6. 【Linux 内核】进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )

    文章目录 一.进程状态 二.进程创建 三.进程终止 ( 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 ) 一.进程状态 Linux 进 ...

  7. 从创建进程到进入 main 函数,发生了什么?

    作者 | 轩辕之风O 来源 | 编程技术宇宙(ID:xuanyuancoding) 头图 |  CSDN 下载自东方IC 前几天,读者群里有小伙伴提问:从进程创建后,到底是怎么进入我写的 main 函 ...

  8. Linux 进程控制 :进程创建,进程终止,进程等待,程序替换

    进程创建 进程终止 进程等待 程序替换 进程创建 fork函数 创建一个子进程,父子进程代码共享,数据独有 #include <unistd.h> pid_t fork(void); 返回 ...

  9. 模拟进程创建、终止、阻塞、唤醒原语_操作系统第二章--进程的描述与控制

    操作系统第二章--进程的描述与控制 前趋图和程序执行 前趋图 前趋图是一个有向无循环图DAG,用来描述进程之间执行的前后关系 初始结点:没有前趋的结点 终止结点:没有后继的结点 重量:表示该结点所含有 ...

最新文章

  1. Datawhale来杭电啦!
  2. linux nohup 英文全称 no hang up(
  3. python官方网站地址-index
  4. SpringBoot - 构建监控体系02_定义度量指标和 Actuator 端点
  5. 07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存
  6. 【库】/lib64/libc.so.6: version `GLIBC_2.14' not found问题
  7. mysql_connect报告”No such file or directory”错误的解决方法
  8. 2018-2019-2 20175320实验三《敏捷开发与XP实践》实验报告
  9. Python之 continue继续循环
  10. 使用 DateTimePicker 控件显示和选择时间
  11. 麦克纳姆轮全向移动机器人运动学模型应用
  12. clover更新驱动 后不能开机_黑苹果笔记本电池模式下省电驱动,延长笔记本续航...
  13. 【BZOJ4818】序列计数(动态规划,生成函数)
  14. 【codeforces 534B】Covered Path
  15. python 自动交易_Python自动化交易入门
  16. Matlab中textscan函数用法
  17. 求职必看~10分钟读懂国企、事业单位和公务员的区别
  18. namesilo域名注册教程
  19. Python3 Mac剪切板存取内容-xerox
  20. CLIP:从自然语言监督中学习可迁移的视觉模型

热门文章

  1. 多云管理平台发展的几个阶段
  2. 游戏开发小结——通过射线投射来创建子弹孔
  3. ROS功能包在线把速腾聚创点云格式转为velodyne点云格式
  4. 狂风测试大师 2003 下载
  5. java初学者快捷施法_新手JAVA程序员学习随笔--快捷键(Mac)(一)
  6. angular-1.2.32路由控制写法与《SPA设计与架构》写法的部分区别
  7. 支原体检测丨艾美捷支原体检测试剂盒解决方案
  8. 春计算机试题答案,2006春计算机专业试题答案(A卷).doc
  9. android:ellipsize = marquee 跑马灯,TextView设置android:ellipsize=marquee不滚动
  10. Mac使用鼠标滚轮方向与Win相反的解决办法