Linux环境编程06

进程的基本概念:
    1、程序与进程
        程序就是存储在磁盘上的可执行文件,当程序被加载到内存中开始运行时就叫做进程。
        一个程序可以被多次加载生成多个进程,进程就是处于活动状态的计算机程序
    2、进程的分类
        进程一般分为三种类型:交互进程、批处理进程、守护进程
            守护进程一般都处于活跃状态,运行在后台,由操作系统在开机时通过启动脚本自动的创建
    3、查看进程
        简单形式:ps    显示当前用户的有终端控制的进程信息
        列表形式:ps -auxw  显示出所有进程的详细信息
            a   所有用户的有终端控制的进程
            x   无终端控制的进程
            u   显示进程的详细信息 
            w   以更长的列宽显示

            USER    进程的属主        
            PID     进程号 
            %CPU    CPU的使用率
            %MEM    内存的使用率
            VSZ     虚拟内存使用的字节数
            RSS     物理内存使用的字节数
            TTY     终端设备号  ?表示无终端控制
            STAT    进程的状态
                O   就绪,等待被调度 *
                R   运行态,在Linux中没有O,就绪也用R表示 *
                S   可被唤醒的睡眠,列如系统中断、获取资源、收到信号时也可以唤醒该进程,转入运行态 *
                D   不可被唤醒的睡眠,只能被系统唤醒
                Z   僵尸态 僵死**
                T   暂停态,收到SIGSTOP信号进入暂停态,收到SIGCONT信号转入运行态 *
                W   等待内存分页(Linux 2.6 后废除)
                X   死亡态      
                <   高优先级
                N   低优先级
                l   多线程的进程
                s   进程组的领导者
                L   有内存页被锁在内存中
                +   位于后台的进程组

            START   进程启动的时间
            TIME    进程运行的时间
            COMMAND 启动进程的命令

    4、父进程、子进程、孤儿进程和僵尸进程
        一个进程是可以被另一个进程创建,创建者叫做父进程,被创建者叫做子进程,子进程被父进程启动后会在操作系统的统一调度下同时运行
        僵尸进程:该进程已死亡,但是父进程没有立即回收它的相关资源,该进程就会进入僵尸状态
        孤儿进程:父进程先于子进程结束,子进程就变成了孤儿进程,孤儿进程会被孤儿院(init 守护进程)领养,init就是孤儿进程的父进程
    
    5、进程标识符
        每个进程都有一个非负整数表示的唯一的标识,即进程ID/PID 
        进程ID在任意时刻内都是唯一的,但是可以重用,进程一旦结束后它的ID会被系统回收,
        但是会过一段时间后才重新分配给其它新创建的进程使用(延时重用)
        pid_t getpid(void);
        功能:获取当前进程的ID
        pid_t getppid(void);
        功能:获取父进程ID
        init进程的ID永远是1

创建进程:
    pid_t fork(void);
    功能:创建子进程
    返回值:一次调用两次返回,子进程返回0,父进程会返回子进程的ID,当进程的数量超过系统的限制时会创建失败,会返回-1给调用者

    该函数调用后父子进程各自独立运行,谁先返回不确定,但是可以通过睡眠确定让哪个进程先执行
    可以根据返回值的不同,让父子进程进入不同的分支语句,执行不同的代码

    通过fork函数创建的子进程会拷贝父进程的数据(数据段、bss段、堆、栈、IO缓冲区),与父进程共享代码段,子进程会继承父进程的信号处理方式

    通过fork函数创建的子进程可以共享父进程的文件描述符

    练习1:为进程创建出4个子进程,再为每个子进程创建出两个子进程
                            A 
                    a    a    a    a 
                  b  b b  b b  b b  b  
    注意:为了防止因为共享代码fork会导致产生不想要的子进程,所以使用pause睡眠的方法让子进程不受其它fork的影响

    pid_t vfork(void);
    功能:以加载可执行文件的方式来创建子进程
    返回值:子进程返回0,父进程返回子进程的PID 

    子进程先返回,但是此时子进程并没有创建成功,需要加载一个可执行程序来替换当前子进程的所有资源,
    替换完成后子进程才算创建成功,此时父进程才能返回

    使用exec系列函数加载可执行文件
        extern char **environ;

        int execl(const char *path, const char *arg, ...);
        path:可执行文件的路径
        arg:命令行参数,一般第一个是可执行文件的名字,至少要有一个,以NULL结尾
        【execl("a.out","a.out","-l","-s",NULL)】

        int execlp(const char *file, const char *arg, ...);
        file:可执行文件名字,会根据PATH环境变量的值查找同名的可执行文件
            可以添加PATH的值:
                1、vim ~/.bashrc
                2、在末尾添加 export PATH=$PATH:/home/ubuntu
                3、保存退出后,source ~/.bashrc 生效
                4、把可执行文件放入新添加的目录中
        arg:数组指针

        int execle(const char *path, const char *arg, ..., char * const envp[]);
        path:可执行文件的路径
        arg:数组指针
        envp:环境变量表,父进程可以在加载子进程时,把一张环境变量表传递给子进程

        int execv(const char *path, char *const argv[]);
        path:可执行文件的路径 
        argv:指针数组
        int execvp(const char *file, char *const argv[]);
        file:可执行文件名字,会根据PATH环境变量的值查找同名的可执行文件
        argv:指针数组
        int execvpe(const char *file, char *const argv[], char *const envp[]);
        file:可执行文件名字,会根据PATH环境变量的值查找同名的可执行文件
        argv:指针数组
        envp:环境变量表

        注意:exec系列函数执行正常是不会返回的,当加载可执行文件失败时才会返回-1
            通过exec系列函数创建的子进程不会继承父进程的信号处理函数,但是能够继承父进程的信号屏蔽集
            fork vfork创建的子进程,都可以使用exec系列函数加载可执行文件

            
        练习2:实现出孤儿进程和僵尸进程,通过ps命令确定


进程的正常退出:

进程的异常终止:

子进程回收:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值