ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux进程与终端学习笔记

2021-04-04 23:31:02  阅读:122  来源: 互联网

标签:const 函数 int 笔记 char exit 终端 Linux 进程


Linux进程与终端学习笔记

进程与程序的区别

  • 程序:二进制文件,存储在磁盘上

  • 进程:process,一个程序运行实例

    • 将程序从磁盘加载到内存并分配对应的资源、调度运行
  • 进程实例

    • 汇编指令代码、数据、资源、状态
    • 一个虚拟计算机(进程上下文环境、CPU状态寄存器)
    • 进程资源:虚拟内存、打开的文件描述符表、信号、工作目录…
  • 进程由操作系统来调度管理.

  • 程序是静态的

  • 进程是动态的

创建一个进程:fork

系统调用:fork()

  • 函数原型:pid_t fork(void);
  • 函数作用:创建一个新进程
  • 返回值:
    • -1 :创建子进程失败
    • 0 :在子进程中返回0
    • >0 :在父进程中返回的是子进程的PID

子进程的运行

子进程拷贝父进程

  • 代码、数据、堆栈内存
  • 进程资源:打开的文件描述符、信号、缓冲区…
    在这里插入图片描述

执行一个二进制程序文件

在这里插入图片描述

execvp函数

**函数原型:int execvp (const char file, char const argv[]);

  • 功能说明:将当前进程的代码使用file程序文件代替并执行
  • 参数说明
    • file:要执行的程序名称
    • argv:要执行的程序文件的参数列表,参数列表以NULL指针为结束标记
  • 返回值
    • 成功:无返回值
    • 失败:返回-1,并设置errno值

exec函数簇

  • #include <unistd.h>
  • int execl (const char *path, const char *arg, …);
  • int execlp (const char *file, const char *arg, …);
  • int execle (const char *path, const char *arg, …);
  • int execv (const char *path, char *const argv[]);
  • int execvp (const char *file, char *const argv[]);
  • int execvpe (const char *file, char *const argv[], char *const envp[]);

exec函数簇命名规则

  • L:参数以列表的形式提供
  • V:参数以数组(向量)的方式提供
  • E:为新进程提供新的环境变量
  • P:在用户的绝对路径path下查找可执行文件,该文件必须在用户路径下,可以只指定程序文件名

写时复制(COW)与vfork

一个新进程的诞生:虚拟空间

在这里插入图片描述

一个新进程的诞生:物理空间

在这里插入图片描述

一个新进程的诞生

在这里插入图片描述

写时复制(copy-on-write)

对fork-exec流程的改进

  • 对于代码段、数据段等,父子进程可以共享,节省拷贝开销
  • 父子进程的页表项均指向同一块物理内存页帧
  • 当子进程进程空间的内容要修改时,才会真正将段复制到子进程
  • 写时复制:
    • 仅仅为子进程复制父进程的虚拟页表项
    • 对将要修改的页面修改页表项

在这里插入图片描述

系统调用:vfork

  • 对fork的改进
  • 对fork的改进更为彻底、简单粗暴
  • vfork是为子进程立即执行exec的程序而专门设计的
    • 无需为子进程复制虚拟内存页或页表,子进程直接共享父进程的资源,直到其成功执行exec或是调用exit退出
    • 在子进程调用exec之前,将暂停执行父进程

进程的退出

终止当前进程exit函数

  • POSIX标准和ANSI C定义的标准函数
    • #include <stdlib.h>
    • 其实是对系统调用_exit的封装
  • 函数原型:void exit (int status);
  • 函数功能:终止当前进程
  • 参数说明:用于标识进程的退出状态,shell或父进程可以获取该值
    • 0:表示进程正常退出
    • -1/1:表示进程退出异常
    • 2~n:用户可自定义

exit函数背后

执行流程

  • 调用退出处理程序(通过atexit、on_exit注册的函数)
  • 刷新stdio流缓冲区
  • 使用由status提供的值执行_exit系统调用函数
    • 关闭进程打开的文件描述符、释放进程持有的文件锁
    • 关闭进程打开的信号量、消息队列
    • 取消该进程通过mmap创建的内存映射

atexit/on_exit

  • 退出处理程序
  • 在exit退出后可以自动执行用户注册的退出处理程序
  • 执行顺序与注册顺序相反
  • 函数原型:int atexit (void (*function)(void));
  • 函数原型:int on_exit (void (*function)(int , void *), void *arg);

TIPS

return与exit的区别

  • exit用来终止当前进程,将控制权交给操作系统
  • return用来退出当前函数,销毁栈帧,返回到上级函数执行
  • 终止进程:
    • 正常退出:exit、_exit、从main函数return
    • 异常退出:调用abort、信号ctrl + C

exit_group函数

  • 函数原型: void exit_group (int status);
  • exit:退出当前进程process
  • exit_group:退出一个进程中所有threads
  • Linux系统特有的系统调用,不属于POSIX标准

other

  • fork之后、exec之前,使用exit是不安全的
  • 很多资源还是共享的(如文件描述符、缓冲区)

exit与_exit

两者的区别

  • exit是库函数是对_exit系统调用的封装
  • 在调用_exit之前,它会执行各种动作
    • 调用退出处理程序(通过atexit和on_exit注册的回调函数)
    • 刷新stdio流缓冲区
    • 使用由status提供的值执行_exit系统调用

_exit的执行流程

  • 关闭进程打开的文件描述符、释放该进程持有的文件锁
  • 关闭该进程打开的信号量、消息队列
  • 取消该进程通过mmap()创建的内存映射
  • 将该进程的所有子进程交给init托管
  • 给父进程发送一个SIGCHLD信号
  • ……

_exit和exit总结

  • 在一个进程中,直接调用_exit终止进程,缓冲区的数据可能会丢失
  • 在创建子进程的应用中,只应有一个进程(一般为父进程)调用exit终止,而其他进程应调用_exit()终止。从而确保只有一个进程调用退出处理程序并刷新stdio缓冲区
  • 如果一个进程使用atexit/on_exit注册了退出管理程序,则应使用exit终止程序的运行,否则注册的回调函数无法执行

标签:const,函数,int,笔记,char,exit,终端,Linux,进程
来源: https://blog.csdn.net/m0_38139533/article/details/115434239

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有