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

相关推荐
泯仲2 分钟前
Ragent项目7种设计模式深度解析:从源码看设计模式落地实践
java·算法·设计模式·agent
fanged3 分钟前
操作系统番外1(Linux的测试体系)(TODO)
linux·运维·服务器
wangchunting19 分钟前
Jvm-垃圾收集器
java·开发语言·jvm
weixin_4643076329 分钟前
QT智能指针
java·数据库·qt
架构师沉默32 分钟前
程序员如何避免猝死?
java·后端·架构
Zzxy1 小时前
快速搭建SpringBoot项目并整合MyBatis-Plus
java·spring boot
星如雨グッ!(๑•̀ㅂ•́)و✧1 小时前
WebFlux onErrorContinue 和 onErrorResume使用详解
java·人工智能
电商API&Tina1 小时前
电商数据采集API接口||合规优先、稳定高效、数据精准
java·javascript·数据库·python·json
123过去2 小时前
pixiewps使用教程
linux·网络·测试工具·算法·哈希算法
zdl6862 小时前
Spring Boot文件上传
java·spring boot·后端