• Linux进程控制


    目录

    一、进程创建

    1.pid_t fork(void)

    2.pid_t vfork(void)

    二、进程终止

    1.退出场景

    2.常见退出方法

    2.1从main中返回

    2.2调用库函数exit

    2.3系统调用接口_exit

    相关知识扩展

    三、进程等待

    1.功能与作用

    2.进程等待的方法

    2.1wait方法

    2.2waitpid方法

    四、程序替换

    1.相关概念

    1.1程序

    1.2程序替换原理

    1.3程序替换目的

    2.相关操作函数

    2.1exec函数簇


    一、进程创建

    1.pid_t fork(void)

    写时拷贝的方式创建一个新的子进程,父子进程代码共享,数据独有

    例:

    创建的子进程会复制父进程pcb中大部分信息,与父进程的虚拟地址空间是相互独立的,但是该块内存是属于父进程的,子进程若要对数据进行修改,会触发写时拷贝技术,系统会为子进程重新开辟空间,将数据拷贝进去,并修改子进程的映射关系(此时两个进程对应数据的虚拟地址相同,但是实际存储地址不同,互不影响)。

    2.pid_t vfork(void)

    创建一个新的子进程,父子进程共用同一个虚拟地址空间

    特性:

    因为vfork创建子进程后,父子进程共用虚拟地址空间,因此用的是同一个栈,一个进程对数据做修改,也会体现在另一方。

    这样会有一个大的隐患,调用栈混乱,因此vfork创建子进程后,父进程需要阻塞,直到子进程退出或进行了程序替换,创建了自己的地址空间以及各项数据。

    例:

    父子进程共用同一个虚拟地址空间,所以映射到的物理内存也相同,一个进程对数据进行了修改,另一个进程内也会体现。

    其实vfork是早期为了提高进程创建效率而提出来的,但是在fork实现了写时拷贝技术之后,就很少使用了。

    二、进程终止

    即如何退出一个进程。

    1.退出场景

    · 正常退出:符合预期结果退出;不符合预期结果退出

    运行到了main的return,或exit接口后退出。

    · 异常退出

    程序没有运行完毕,中途崩溃退出。

    2.常见退出方法

    2.1从main中返回

    注意:return只有在main中才是退出运行,在其他函数中只是退出对应函数。

    2.2调用库函数exit

    库函数:void exit(int return_val)

    可以在程序代码的任意位置进行调用,用于退出程序的运行;退出前会刷新缓冲区数据到文件。

    2.3系统调用接口_exit

    系统调用接口:void _exit(int retturn_val)

    可以在程序代码的任何位置进行调用,用于退出程序的运行;直接退出释放资源。

    相关知识扩展

    1.库函数与系统调用接口的关系

    库函数是针对典型应用功能对系统调用接口进行的封装,以便于使用。

    2.buff-缓冲区&cache-缓存

    · buff-缓冲区

    相对于文件来说就是数据写入文件前,先放到缓冲区中,待积累成为大数据一次性刷新缓冲区写入文件,减少IO次数。

    · cache-缓存

    相对于文件来说就是从文件中读取数据,一次拿出的是一个磁盘块的数据放到内存中,下一次读取数据的时候先从缓存中对比。

    3.如何获取上一步系统调用接口的错误原因

    void perror("fork error");

    获取上一步系统调用接口的错误原因。

    char* strerror(int errno);

    printf("fork error:%s\n",strerror(errno));等价于perror

    注:int errno是全局变量,用于存放上一次系统调用的错误原因编号。

    三、进程等待

    1.功能与作用

    父进程创建子进程后,等待子进程退出,获取子进程的退出返回值,释放子进程资源,避免僵尸进程的产生。

    2.进程等待的方法

    #include

    2.1wait方法

    pid_t wait(int* status);

    阻塞等待任意一个子进程的退出,使用status作为输出参数获取子进程的退出返回值。

    返回值

    成功,返回处理的这个退出的子进程的进程ID;失败,返回-1。

    2.2waitpid方法

    pid_t waitpid(pid_t pid,int* status,int options);

    参数:

    pid_t pid:指定要等待的子进程ID;-1则表示等待任意一个子进程。

    int* status:输出参数,用于向外界返回退出子进程的返回值。

    1)异常退出码获取:WIFEXITED(status)  正常终止返回true

    2)进程退出返回值获取:WEXITSTATUS(status)

    int options:操作选项:

    0——阻塞等待;

    WNOHANG——设置接口为非阻塞:有子进程,但是没有退出,则waitpid接口直接返回0,不阻塞。

    返回值:

    成功等待子进程退出,返回子进程的pid;失败,即当前没有子进程,返回0;出错,返回-1。

    注意:

    1.wait/waitpid接口都是等待一个子进程退出,但是如果在调用接口等待的时候,已经有子进程退出了,则会直接进行处理退出的子进程,处理完毕,接口返回。

    2.waitpid的非阻塞使用时,一定要循环操作,否则操作就有可能没有完成,依然可能产生僵尸进程。

    四、程序替换

    1.相关概念

    1.1程序

    程序就是一堆静态的指令和数据,运行的时候被加载到内存种,然后系统创建pcb管理程序的运行。

    创建一个进程,就是创建了一个pcb,子进程复制了父进程,所以运行的代码和父进程是一样的。这样就可以分摊任务处理压力,但主要目的是进程替换,让子进程管理另一个程序的运行。

    1.2程序替换原理

    将一个新的程序加载到内存中,然后改变一个进程的页表映射信息,将其更改到新的程序的指令和数据上,这时当前的pcb管理的就不再是原来的程序运行,而是一个新的程序。

    1.3程序替换目的

    进行程序替换,让一个进程运行指定的程序,完成对应的功能,常用于子进程的替换。

    2.相关操作函数

    2.1exec函数簇

    extern char **environ;

    int exece(const char *path,char *const argv[],char *const envp[]);系统调用接口

    const char *path:要加载替换的新程序的文件路径名称

    char *const argv[]:程序的运行参数

    char *const envp[]:进程的环境变量

    以下五个函数是对系统调用接口的封装:

    int execl(const char *path,const char *arg,....)

    path:待路径的新程序名称

    arg:参数,是一个不定参

    int execlp(const char *file,const char *arg,....)

    file:不带路径的新程序名称,在path环境变量指定的路径下去找程序,常用于指令程序的替换。

    int execle(const char *path,const char *arg,....,char * const envp[])

    path:带路径的新程序名称

    arg:参数

    envp:环境变量

    int execv(const char *path,char * const argv[])

    与execl类似,区别是参数不是一个一个给,而是组织成为一个字符指针数组一次性给。

    int execvp(const char *file,char * const argv[])

    对标execlp,在指定路径下寻找程序,参数通过数组给定。

    函数簇特点区分:

    l和v的区别,在于参数是一个一个给,还是组织成为数组一次性给;

    有没有p的区别,在于是否会默认到path环境变量指定的路径下找程序;

    有没有e的区别,在于是否需要自定义环境变量。

  • 相关阅读:
    BUUCTF 金三 1
    论文笔记(整理):轨迹相似度顶会论文中使用的数据集
    什么是JavaScript的事件驱动编程(event-driven programming)?
    【论文笔记合集】ARIMA 非平稳过程通过差分转化为平稳过程
    C4模型理解
    阿里云linux安装docker 以及常见遇见的坑
    洗地机怎么选?2023年洗地机推荐
    新型PC模拟器外挂肆虐,游戏安全攻防再升级
    你有对象类,我有结构体,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang结构体(struct)的使用EP06
    金山终端安全系统V9.0 SQL注入漏洞复现
  • 原文地址:https://blog.csdn.net/m0_63020222/article/details/126391876