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 结尾的文件。

相关推荐
tongyiixiaohuang14 分钟前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
鱼宵1 小时前
取集合第一个元素,Java 为什么要写三种写法?
java·windows·python·java21
学长毕设1 小时前
基于SpringBoot的餐厅管理系统-附源码
java·spring boot·后端
沫璃染墨1 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
Kobebryant-Manba1 小时前
C/S和B/S结构
运维·服务器
刚入门的大一新生1 小时前
Linux-线程互斥
java·开发语言
赵小哥要冲啦2 小时前
社区邻里互助小程序从 0 到 1 复盘:需求拆解与信任机制设计
java·小程序·需求分析
xiaogai_gai2 小时前
采购业务退款单同步实战:从钉钉审批流到金蝶云星空付款单
java·数据库·钉钉
二哈赛车手2 小时前
新人笔记---hermes定时功能设计,具体讲解以及可优化点
java·人工智能·笔记·spring·ai·typescript
ZWZhangYu2 小时前
从 Dify 实践理解大模型上下文缓存
java·后端·spring