您的位置:首页 > 运维架构 > Linux

【Linux-8】操作系统之进程问题

2019-05-30 23:42 127 查看

目录:

  1. 进程控制
  2. 进程创建,fork/vfork
  3. 进程等待
  4. 进程程序替换
  5. minishell
  6. 进程终止

1.进程控制:进程创建-->进程终止-->进程等待-->程序等待

2.进程创建

fork-->通过复制调用进程创建一个新的子进程:
                  复制(pcb--代码共享,数据独有)  --程序计数器(运行的位置也一样)
                  返回值:对于父进程来说:fork返回值是子进程的pid:创建子进程失败返回0;
           创建一个子进程的流程:写时拷贝技术
           vfork-->创建子进程,共用同一个虚拟地址空间,为了防止调用栈混乱,因此父进程vfork会阻塞,阻塞父进程直到子进程exit退出或程序被替换重新开辟自己的空间以及虚拟地址空间页表;不能return退出,会导致程序崩溃
            fork/vfork在内核中创建进程都是调用【clone函数】实现pcb创建并拷贝数据的

进程终止:进程的退出
                        退出场景:
                                    正常退出:结果符合预期   / 异常退出:结果不符合预期,--->常见的程序崩溃
                        如何退出:
                                    exit(int retval);_exit(int retval);
                                    main函数中的return            退出前刷新缓冲区
                                    void exit(int status);    这是一个库函数           退出前刷新缓冲区
                                    void _exit(int status);   任意一个位置退出进程  不会刷新缓冲区,数据被丢弃
                                main exit
                                获取子进程

3.进程等待

等待子进程退出,获取子进程的退出返回值,避免子进程成为僵尸进程。
                            为什么?--->因为子进程退出时为了保存退出原因,因此操作系统不能释放子进程全部原因,而父进程没有关注到子进程的消息,导致子进程成为僵尸进程。
                           若父进程获取了子进程的返回值,僵尸进程没有了存在的意义就会被释放资源。因为父进程不知道子进程何时退出?创建之后一直等着。
                            如何等待?--->wait(int *statu)接口/waitpid接口 一直等待子进程退出,退出后获取返回值,放到statu里
                                        如果子进程一直未退出,wait函数将一直阻塞
                                        wait等待任意一个子进程退出,waitpid可以等待指定的一个子进程退出,并且可以设置为非阻塞。
                                        阻塞:为了完成某个功能,发起系统调用,当前若不具备完成条件,则等待条件具备,完成功能后返回
                                        非阻塞:为了完成某个功能,发起系统调用,当前若不具备完成条件,侧立即报错返回
                                    erron(存储错误原因)
                                    perror(直接打印上一次出错的错误信息)
                                    strerror(通过字符串编号获取字符串错区原因)
                                pid= -1:等待任意一个子进程
                                pid> 0:等待指定子进程
                                WNOHANG:将wait_pid设置为非阻塞 ,0默认阻塞
                            返回值:若WNOHANG被指定,没有子进程返回-1,错误返回0;
                                statu中高16位没有使用;低16位中的高8位存储子进程退出返回值,低8位中的高1位存储core dumped(核心转储标志)核心转储【默认关闭的】:程序异常退出时保存程序的运行信息,便于事后调试(不安全)【默认关闭】
                                若低8位里面的低7位是0,表示没有异常退出情况,表示程序正常退出;负责表示异常,返回值无意义
                                 获取低7位:statu & 0x7f
                                 获取低16位里的高8位:statu >> 8 & 0xff(最大返回255) 257返回1

4.进程程序替换

程序替换:替换一个进程正在运行的程序

重新加载一个新的程序到物理内存中,对一个进程的代码段通过页表在物理内存中的地址进行修改映射关系,让程序的代码段经过页表转换后,指向了新的程序位置。

让一个进程PCB通过页表转换映射到物理地址上另一个程序的地址;进程将运行另一个程序;以前的数据和代码都失效了,因此需要重新初始化页表以及虚拟地址空间中的代码段和数据段。

如何进行程序替换:exec函数族

带p和不带p的区别:加载程序时是否需要确定给出所在路径。

v和l的区别:程序的运行参数是函数的参数平铺或者直接组织成为字符串指针数组给予。

带e/不带e:运行程序,是否需要重新定义环境变量。

5.minishell

自主实现minishell:简单的命令行解释器


    scanf("%[^\n]%*c",tmp);获取一个连续的字符串
    %[^\n]:从标准输入缓冲区取数据直到遇到\n停止。
    %*c:将缓冲区中剩下的\n中取出来;否则造成死循环。
minishell:
    shell中处理外部命令是通过创建子进程后程序替换完成功能;还有一部分命令是内建命令,也就是shell自身实现的功能,比如 cd 改变当前所在路径。    

 

 

 

 

 

~未完待续,bye~

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: