Linux软件编程:进程管理

一、进程基本概念

1. 程序与进程

  • 程序:静态的,存储在硬盘上的指令和数据的集合。

  • 进程:程序的一次执行过程,是系统进行资源分配和调度的基本单位,具有创建、执行、调度和终止的生命周期。


二、进程相关命令

1. 进程查看

  • top:实时查看系统进程及资源占用情况。

  • ps -ef:查看系统所有进程的详细信息。

  • ps -aux:查看进程状态、CPU和内存使用情况。

  • ps -ef | grep 进程名:查找指定进程。

2. 进程控制

  • kill -9 PID:强制终止指定PID的进程。

  • killall -9 进程名:终止所有同名进程。

  • &:在后台运行程序,如 ./a.out &

  • jobs:查看当前终端的所有后台任务。

  • fg 编号:将后台任务调至前台执行。

  • nice -n 优先级 任务:以指定优先级运行进程。

  • renice -n 优先级 PID:修改运行中进程的优先级。


三、进程的创建与地址空间

1. 虚拟地址与物理地址

  • 虚拟地址:通过MMU映射后进程可访问的内存空间。

  • 物理地址:实际的RAM地址,用户无法直接访问,需通过虚拟地址映射。

2. 虚拟地址空间布局(0-4G)

  • 文本段 (.text):存放程序代码。

  • 数据段

    • .rodata:只读数据(如字符串常量)。

    • .data:已初始化的全局变量和静态变量。

    • .bss:未初始化的全局变量和静态变量(进程启动时清零)。

  • 栈区 (.stack):存放局部变量,默认8M,由高向低增长。

  • 堆区 (.heap):动态分配内存区域,由低向高增长。

  • 内核空间:用户无法直接访问。

3. 进程空间独立性

  • 每个进程拥有独立的虚拟地址空间,映射到不同的物理内存区域,确保进程间互不干扰。

四、进程调度算法

  1. 先来先服务 (FCFS)

  2. 短作业优先 (SJF)

  3. 高优先级调度

  4. 时间片轮转 (RR):每个进程分配一个时间片(通常5-10ms),宏观上并行,微观上串行。

  5. 多级队列反馈调度

  6. 负载均衡调度

  7. 抢占式调度


五、进程状态

  • 运行态 (R):正在CPU执行。

  • 就绪态 (R):已准备好,等待CPU调度。

  • 可唤醒等待态 (S):等待资源,可被唤醒。

  • 不可唤醒等待态 (D):等待资源,不可中断。

  • 停止态 (T):被用户暂停。

  • 僵尸态 (Z):进程已结束,资源未回收。

  • 结束态 (X):进程结束且资源已回收。


六、进程相关函数接口

1. fork() -- 创建子进程

c

复制代码
pid_t fork(void);
  • 子进程复制父进程的代码、数据、堆栈等空间。

  • 父进程返回子进程PID,子进程返回0,失败返回-1。

2. getpid() -- 获取当前进程PID

c

复制代码
pid_t getpid(void);

3. getppid() -- 获取父进程PID

c

复制代码
pid_t getppid(void);

七、编程练习与实践

练习1:创建子进程并打印PID

创建两个子进程,分别打印自己的PID和父进程PID,父进程打印自己的PID和两个子进程的PID。

复制代码
末尾的while(1)也可以不用,但要再父进程打印那里加上一个sleep(5)函数,这是为了防止父进程提前结束,使得子进程的getppid()函数返回值错误



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

int main(void)
{
    pid_t ret1 = 0;
    pid_t ret2 = 0;

    ret1 = fork();

    if(-1 == ret1)
    {
        perror("fail to fork");
        return -1;
    }

    if(0 == ret1)
    {
        printf("我是子进程1: pid : %d ppid: %d\n", getpid(), getppid());
    }
    else if(ret1 > 0)
    {       
        ret2 = fork();

        if(-1 == ret2)
        {
            perror("fail to fork");
            return -1;
        }

        if(0 == ret2)
        {
            printf("我是子进程2: pid : %d ppid: %d\n", getpid(), getppid());
        }

        else if(ret2 > 0)
        {
            printf("我是父进程: pid : %d childpid1: %d childpid2: %d\n", getpid(), ret1, ret2);
        }


    }
    
    while(1)
    {

    }

    return 0;
}

练习2:遍历目录查找媒体文件

遍历指定目录,打印所有以 .flv.avi.rmvb.rm 结尾的文件。

相关推荐
安科士andxe6 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
小白同学_C9 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖9 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
青云计划9 小时前
知光项目知文发布模块
java·后端·spring·mybatis
儒雅的晴天10 小时前
大模型幻觉问题
运维·服务器
赶路人儿10 小时前
Jsoniter(java版本)使用介绍
java·开发语言
探路者继续奋斗10 小时前
IDD意图驱动开发之意图规格说明书
java·规格说明书·开发规范·意图驱动开发·idd
通信大师11 小时前
深度解析PCC策略计费控制:核心网产品与应用价值
运维·服务器·网络·5g
不做无法实现的梦~11 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
消失的旧时光-194311 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言