进程的相关命令,进程的创建、调度、消亡,进程相关函数接口

我要成为嵌入式高手之2月23日Linux高编第八天!!

学习笔记

进程

一、进程基本概念

程序:存放在外存中的一段数据组成的文件

进程:是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡

二、进程相关命令

1、top

        动态查看当前系统的所有进程信息(根据CPU占用率排序)

        PID:唯一识别进程的ID号(>0)

        优先级:Linux系统中数值越低优先级越高(-20~+19),Windows相反

        进程状态:

                R:运行态/就绪态

                S:睡眠态/可唤醒等待

                D:不可唤醒等待态

                T:暂停态

                Z:僵尸态

                X:结束态

        q退出

2、nice

        优先级(NI)默认为0

        以指定优先级来运行进程

        示例:nice -n 优先级 要执行的进程任务

3、renice

        重新设定一个正在运行的进程的优先级

        示例:renice -n 优先级 进程PID

4、kill

        杀死指定的进程任务

        示例:kil -9 进程PID

5、killall

        杀死进程名对应的所有进程任务

        示例:killall -9 进程名

6、ps -ef

        查看当前时刻所有进程的信息

        PPID:父进程的ID号

        ps -ef | grep a.out

7、pstree

        查看进程树关系

8、ps -aux

        TTY 查看当前进程依赖于哪个终端

9、./a.out &

        将a.out放在后台执行

        fg 数字:将第几个程序放在前台执行

10、jobs

        查看一个终端下后台执行的任务

三、进程的创建

32bits的操作系统:

        有32位地址总线(4字节)

        一个进程在运行时,操作系统会为该进程分配0~4G虚拟内存空间,分为文本段、数据段、系统数据段;通过mmu内存映射单元,虚拟地址和物理地址完成映射。

1、操作系统管理的区域

        文本段:也成为文本区,存放代码和指令

        数据段:也成为数据区,可以细分为①字符串常量区②已初始化静态变量和全局变量区③未初始化静态变量和全局变量区

        系统数据段:堆区和栈区

            ①栈区:1)局部变量存放在栈区

         基本8mb:2)未经初始化为随机值

                           3)代码执行到变量定义时为变量开辟空间

                           4)当变量的作用域结束时回收空间

                           5)栈的增长方向,自高向低增长

            ②堆区:1)程序员手动管理(malloc)

                           2)malloc才能申请到堆区空间,free才能释放堆区空间

                           3)增长方向:自低向高

             ③数据区:1)静态变量、全局变量、字符串常量存放在数据区

                               2)编译时开辟空间,执行时将该空间加载到内存中

                               3)未经初始化为0值

                               4)程序结束回收数据区

             ④文本区:1)存放代码和指令

2、进程中虚拟内存地址和实际物理内存地址的关系

        1、0-4g虚拟内存空间只有一个

        2、实际物理地址中每个进程空间是独立的

        3、通过mmu内存映射单元,当一个进程执行时,将物理地址中的数据加载到虚拟地址中运行

四、进程的调度

1、常见的调度算法

        ①先来先执行,后来后执行

        ②高优先级调度

        ③时间片轮转调度算法

                时间片:CPU在一个任务中的运行时间成为一个时间片

        ④多级队列反馈的调度算法

        ⑤负载均衡的调度算法

2、核心思想:宏观串行,微观并行

3、进程的状态:

        R        运行态(占用CPU资源)、就绪态(随时准备调度)

        S        睡眠态/可唤醒等待态

        D        不可唤醒等待态(不能被打断/切换的任务)

        T        暂停态(程序运行暂停住了,不占用CPU资源)

        Z        僵尸态(进程代码执行完了,空间未被回收)

        X        结束态(都执行完毕,空间也被回收完)

五、进程相关函数接口

1、fork

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

功能:创建一个子进程空间,新创建的进程称为原来进程的子进程,原来的进程称为父进程

返回值:

        成功:子进程返回0;父进程返回子进程的PID

        失败:失败返回-1;

父进程调用fork创建子进程,子进程拷贝父进程的文本段,数据段,系统数据段

2、getpid

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);

功能:获得调用这个进程的pid号

3、getppid

pid_t getppid(void);

功能:获得调用进程的父进程的pid

#include "head.h"

int main(void)
{
    pid_t pid;

    pid = fork();

    if (pid == 0)
    {
        printf("This is Child Process! PID:%d PPID:%d\n", getpid(), getppid());
    }
    else if (pid > 0)
    {
        printf("This is Parent Process! PID:%d Child PID:%d\n", getpid(), pid);
    }
    printf("hello world!\n");

    while (1)
    {

    }

    return 0;
}

练习:创建一个父进程的两个子进程,子进程中打印自己的pid和父进程的pid,父进程中打印自己的pid和两个子进程的pid

#include "head.h"

int main(void)
{
    pid_t pid1;
    pid1 = fork();
    pid_t pid2;

    if (-1 == pid1)
    {
        perror("fail to fork1");
        return -1;
    }

    if (pid1 == 0)
    {
        printf("First Child Process! PID1:%d PPID:%d\n", getpid(), getppid());
    }
    else if (pid1 > 0)
    {
        pid2 = fork();
        if (pid2 == -1)
        {
            perror("fail to fork2");
            return -1;
        }
        if (pid2 == 0)
        {
            printf("Second Child Process! PID2:%d PPID:%d\n", getpid(), getppid());
        }else if (pid2 > 0)
        {
            printf("Parent Process! PID:%d PID1:%d PID2:%d\n", getpid(), pid1, pid2);
        }
       
    }

    while (1)
    {

    }

    return 0;
}

4、exit

#include <stdlib.h>

void exit(int status);

功能:让进程结束、刷新缓存区

参数:status:进程结束的状态

返回值:缺省

exit在主函数中使用和return效果一致

#include "head.h"

int main(void)
{
    printf("hello world!");
    exit(0);
    printf("how are you");

    return 0;
}

5、_exit

#include <unistd.h>

void _exit(int status);

功能:直接让进程结束,不刷新缓存区

参数:status进程结束的状态

返回值:缺省

#include "head.h"

int main(void)
{
    printf("hello world!");
    _exit(0);
    printf("how are you");

    return 0;
}

六、进程的消亡 

1、僵尸进程:

        进程代码执行结束,但是空间代码没有被回收

2、如何避免产生僵尸态?

        1)让父进程先结束

        2)让父进程回收子进程空间

3、孤儿进程:

        进程的父进程先结束,此时该进程成为孤儿进程,此时被系统进程收养(1995)进程在结束时会被系统进程回收进程空间

4、wait

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *wstatus);

功能:回收子进程空间,会阻塞,有同步功能

参数:wstatus 存放子进程结束状态空间的首地址

返回值:成功返回回收到的子进程的pid,失败返回-1;

七、练习

        创建一个进程的9个子进程,子进程中打印自己的PID和父进程的PID 父进程中打印自己的PID和9个子进程的PID

#include "head.h"

int main(void)
{
    pid_t pid[9] = {0};
    int i = 0;
    for (i = 0; i < 9; ++i)
    {
        pid[i] = fork();
        if (-1 == pid[i])
        {
            perror("fail to forki");
            return -1;
        }
        if (pid[i] == 0)
        {
            printf("Child[%d]: %d    Parent: %d\n", i+1, getpid(), getppid());
            break;
        }
    }

    sleep(1);
    if (pid[i] > 0)
    {
        printf("Parent: %d\n", getpid());
        for (i = 0; i < 9; ++i)
        {
            printf("Child[%d]: %d\n", i+1, pid[i]);
        }
    }
    
    while (1)
    {
        sleep(5);
        break;
    }

    return 0;
}

  • 41
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值