• 《Linux系统编程》-----DAY3


    进程

    ​ 程序---死的,存在磁盘上,不占用系统资源,编译好的二进制文件

    ​ 进程---活得,运行的程序,占用系统资源

    每个Linux进程都一定有一个唯一的数字标识符,称为进程ID(process ID)。进程ID总是一非负整数。
    Linux启动过程有个init进程ID号是1,其它进程都是init派生出来的。 Linux启动过程有个init进程ID号是1,其它进程都是init派生出来的。

    Linux下的进程结构

    Linux系统是一个多进程的系统,进程之间具有并行性、互不干扰的特点。
    Linux中进程包含3个段:代码段、数据段、堆栈段
    image

    数据段:存放全局变量常数以及动态数据分配的空间(malloc函数取得的空间)

    代码段:存放程序代码

    堆栈段:存放子程序的返回地址、子程序的参数以及程序的局部变量

    image

    内存管理单元图

    image

    虚拟内存和物理内存映射

    image

    PCB进程控制块

    /usr/src/linux-headers-3.16.0-30/include/linux/sched.h
    

    ​ 文件中查看 struct task_struct结构体定义

    ​ 内部成员:

    ​ 进程id,pid_t

    ​ 进程状态:就绪,运行,挂起,停止

    ​ 进程切换时需要保存和恢复的一些cpu寄存器

    ​ 描述虚拟地址空间的信息

    ​ 描述控制终端的信息

    ​ 当前工作目录

    ​ umask掩码

    ​ 文件描述符表

    ​ 和信号相关的信息

    ​ 用户id和组id

    进程控制

    fork函数

    ​ pid_t fork(void)

    ​ 创建子进程。父进程各自返回,父进程返回子进程pid。子进程返回0

    getpid();
    getppid()

    循环创建5个进程

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    
    
    int main()
    {
        int i;
        for(i=0;i<5;i++){
            if(fork()==0)
                break;
        }
        if(i==5){
            sleep(5);
            printf("I'm parent 
    ");
        }
        else{
            sleep(i);
            printf("I'm %d th
    ",i);
        }
        
        return 0;
    }
    

    进程共享

    ​ 父子进程之间在fork后,有哪些相同,有哪些不同?

    ​ 刚fork之后

    ​ 父子相同处:1.全局变量,2..data、3..text、4.堆、5.栈、6.环境变量、7.用户ID、8.宿主目录、9.进程工作目录、10.信号处理方式

    ​ 父子不同处:1.进程ID 2.fork返回值 3.父进程ID 4.进程运行时间 5.闹钟 6.未决信号集

    ​ 父子进程共享:

    读时共享,写时复制---------全局变量

    ​ 1.文件描述符

    ​ 2.nmap映射区

    参考书:

    ​ 《操作系统原理》 谢青松

    ​ 《计算机硬件及组成原理》 Arnoid S.Berger

    exec函数族

    重点掌握:

    	int execl(const char *path,const char * arg,...);
    
    ​	int execlp(const char *file, const har *arg,...);
    

    ​ 加载一个进程,借助 PATH 环境变量

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

    ​ 成功:无返回;

    ​ 失败:-1

    ​ 参数 1:要加载的程序的名字。该函数需要配合 PATH 环境变量来使用,当 PATH 中 所有目录搜索后没有参数 1 则出错返回。 该函数通常用来调用系统程序。如:ls、date、cp、cat 等命令。

     #include<stdio.h>                                                                                                                                                         
     #include<unistd.h>
     #include<stdlib.h>
     
     int main(int argc,char*argv[]){
     
         pid_t pid=fork();   //创建子进程
         if(pid==-1){
             perror("fork error");
             exit(1);
         }   
         else if(pid==0){    //子进程
              // execlp("ls","-l","-d","-h",NULL);   错误写法
    	     // execlp("ls","ls","-l","-h",NULL);
             //execlp("date","date",NULL);
             //  execlp("./test","./test",NULL);
          
             execl("./test","./test",NULL);
          
             perror("exec error");
             exit(1);
         }   
         else if(pid>0){     //父进程
             sleep(1);
             printf("I'm parent:%d
    ",getpid());
         }   
     
     
         return 0;
     }
    
    

    image

    回收子进程

    孤儿进程(父进程先挂,子进程变成孤儿):

    ​ 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程为init进程

    ​ 称为init进程领养孤儿进程

    僵尸进程(子进程挂了,父进程一直不回收,子进程变成僵尸进程)

    僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的PCB资源,此时子进程将成为一个僵尸进程

    ​ 特别注意,僵尸进程是不能使用kill命令清除掉的。因为kill命令是用来终止进程的,而僵尸进程已经终止。用什么办法可以清除僵尸进程?--------------杀死父进程

    wait函数

    ​ 父进程调用 wait 函数可以回收子进程终止信息。该函数有三个功能:

    1. ​ 阻塞等待子进程退出
    2. ​ 回收子进程残留资源
    3. ​ 获取子进程结束状态(退出原因)。

    pid_t wait(int *status);

    成功:清理掉的子进程 ID;

    ​ 失败:-1 (没有子进程)


    可使用 wait 函数传出参数 status 来保存进程的退出状态。借助宏函数来进一步判断进 程终止的具体原因。宏函数可分为如下三组:

    1.WIFEXITED(status) 为非 0 → 进程正常结束 WEXITSTATUS(status)

    如上宏为真,使用此宏 → 获取进程退出状态 (exit 的参数)

    1. WIFSIGNALED(status) 为非 0 → 进程异常终止 WTERMSIG(status)
      如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。

    2. WIFSTOPPED(status) 为非 0 → 进程处于暂停状态 WSTOPSIG(status)
      如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。 WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行

    waitpid函数 指定某一个进程进行回收

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

    参数:

    ​ pid:指定回收的子进程id、

    ​ >0:待回收的子进程pid

    ​ -1:任意子进程

    ​ 0:同组的子进程

    ​ status:(传出)回收进程的状态

    ​ options:WNOHANG 指定回收方式为:非阻塞

    返回值:

    ​ >0:表示成功回收的子进程pid

    ​ 0:函数调用时,参3指定了WNOHANG,并且,没有子进程结束。

    ​ -1:失败errno

    总结:

    ​ wait,waitpid 一次调用,回收一个子进程

    ​ 想回收多个,循环

    ​ waitpid(-1,&status,0)==wait(&status);

  • 相关阅读:
    Oracle中关于数据库实例名与数据库服务名(转载)
    将集成spring的项目从tomcat上移植到weblogic下存在的问题
    python实例编写(1)--浏览器操作,元素操作
    python webdriver 环境搭建详解
    定位页面元素之xpath详解以及定位不到测试元素的常见问题
    Appium (win7系统)环境搭建----完整版
    SQL基础巩固
    软件测试发展规划
    自动化测试之 seleniumIDE,Selenium1,selenium2和testNG入门
    Android --- 读取系统资源函数getResources()小结
  • 原文地址:https://www.cnblogs.com/hongweijiang/p/14514210.html
Copyright © 2020-2023  润新知