云计算百科
云计算领域专业知识百科平台

Linux软件编程: 进程解析

1 进程基础概念

1.1 程序与进程的区别

程序:存储在硬盘上的静态代码和数据集合,是未执行的指令序列

进程:程序动态执行的实例,包括创建、调度、执行到消亡的完整生命周期

关键区别:

  • 程序是静态的,进程是动态的

  • 程序是存储在存储介质上的文件,进程是内存中的执行实体

  • 一个程序可以对应多个进程,一个进程只能对应一个程序

1.2 进程在操作系统中的角色

进程是操作系统进行资源分配和调度的基本单位,每个进程拥有独立的地址空间和系统资源,确保进程间的隔离性和安全性。

2 进程管理命令详解

2.1 进程查看命令

2.1.1 top命令 – 实时进程监控

top

动态显示系统进程信息,按CPU使用率排序,包含:

  • PID:进程ID(唯一标识)

  • PPID:父进程ID

  • CPU%:CPU使用率

  • MEM%:内存使用率

2.1.2 ps命令 – 进程状态查看

ps -ef # 查看所有进程详细信息
ps -aux # 查看进程状态和资源使用
ps -ef | grep 进程名 # 过滤特定进程
ps -aux | grep 进程名 # 过滤并显示状态

常用选项说明:

  • -e:显示所有进程

  • -f:完整格式显示

  • -u:显示用户相关信息

  • -x:显示没有控制终端的进程

2.2 进程控制命令

2.2.1 进程终止

kill -9 PID # 强制终止指定进程
killall -9 进程名 # 终止所有同名进程

2.2.2 后台任务管理

./program & # 在后台运行程序
jobs # 查看后台任务列表
fg %1 # 将1号后台任务调到前台
Ctrl + Z # 暂停前台任务
bg %1 # 在后台继续运行暂停的任务

2.2.3 进程优先级管理

nice -n 优先级 命令 # 指定优先级运行程序(-20到19)
renice -n 优先级 PID # 修改运行中进程的优先级

优先级说明:

  • 数值越小优先级越高(-20最高,19最低)

  • 普通用户只能降低优先级(0-19)

  • root用户可设置任意优先级

3 进程地址空间与内存管理

3.1 虚拟地址空间布局

每个进程拥有独立的4GB虚拟地址空间(32位系统),分布如下:

0xFFFFFFFF +—————–+
| 内核空间 | 1GB
0xC0000000 +—————–+
| 栈区 | 向下增长
+—————–+
| 堆区 | 向上增长
+—————–+
| 未初始化数据段 | .bss段
+—————–+
| 已初始化数据段 | .data段
+—————–+
| 只读数据段 | .rodata段
+—————–+
| 代码段 | .text段
0x08048000 +—————–+
| 保留区域 |
0x00000000 +—————–+

3.2 内存区域详解

3.2.1 代码段(.text)
  • 存放程序执行的机器指令

  • 只读属性,多个进程可共享同一代码段

  • 在程序编译时确定,运行时不可修改

3.2.2 数据段
  • .data段:已初始化的全局变量和静态变量

  • .bss段:未初始化的全局变量和静态变量(运行时初始化为0)

  • .rodata段:字符串常量等只读数据

3.2.3 堆区(heap)
  • 动态内存分配区域(malloc/free)

  • 手动管理,向高地址增长

  • 需要程序员显式释放内存

3.2.4 栈区(stack)
  • 存放局部变量和函数调用信息

  • 自动管理,向低地址增长

  • 函数返回时自动释放

3.3 地址空间隔离机制

通过MMU(内存管理单元)实现虚拟地址到物理地址的映射,确保:

  • 每个进程拥有独立的地址空间

  • 进程间内存隔离,提高系统稳定性

  • 支持内存共享和写时复制技术

4 进程状态与调度算法

4.1 进程状态转换

创建 → 就绪(R) ↔ 运行(R) → 终止(X)
↓ ↑
等待(S/D) → 就绪(R)

4.1.1 主要进程状态
  • 运行态(R):进程正在CPU上执行

  • 就绪态(R):进程准备就绪,等待CPU调度

  • 可中断等待态(S):等待资源,可被信号中断

  • 不可中断等待态(D):等待硬件资源,不可中断

  • 停止态(T):进程被暂停执行

  • 僵尸态(Z):进程已终止,但资源未回收

  • 死亡态(X):进程完全终止

4.2 进程调度算法

4.2.1 先来先服务(FCFS)
  • 按进程到达顺序调度

  • 实现简单,但可能导致短进程等待时间长

4.2.2 短作业优先(SJF)
  • 优先调度预计执行时间短的进程

  • 最小化平均等待时间,但需要预知执行时间

4.2.3 时间片轮转(RR)
  • 每个进程分配固定时间片(5-10ms)

  • 公平性好,适合交互式系统

  • 宏观并行,微观串行执行

4.2.4 多级反馈队列
  • 结合多种调度策略

  • 动态调整进程优先级

  • 平衡响应时间和吞吐量

5 进程创建与控制函数

5.1 fork函数 – 进程创建

#include <unistd.h>

pid_t fork(void);

功能特性:

  • 创建子进程,子进程是父进程的完整副本

  • 复制文本段、数据段、堆栈等所有资源

  • 父子进程并发执行,执行顺序不确定

返回值说明:

  • 父进程:返回子进程PID(>0)

  • 子进程:返回0

  • 错误:返回-1

5.2 进程信息获取函数

#include <unistd.h>

pid_t getpid(void); // 获取当前进程PID
pid_t getppid(void); // 获取父进程PID

5.3 进程创建实战示例

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

int main(void)
{
pid_t pid;

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

if(pid == 0)
{
printf("我是子进程,PID:%d,PPID:%d\\n",getpid(),getppid());
}
else if(pid >= 1)
{
printf("我是父进程,PID:%d,childPID:%d\\n",getpid(),pid);
}

printf("hello world\\n");

while(1)
{

}
return 0;
}

6.实战应用:媒体文件遍历

6.1 目录遍历与文件过滤

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>

void Listdir(char *pdirpath)
{
DIR *dp = NULL;
struct dirent *pp = NULL;
char filepath[512] = {0};
char *pstr = NULL;

dp = opendir(pdirpath);
if (NULL == dp)
{
perror("fail to opendir");
return;
}

while (1)
{
pp = readdir(dp);
if (NULL == pp)
{
break;
}

if ('.' == pp->d_name[0])
{
continue;
}
pstr = pp->d_name;

while(pstr[0] != '.')
{
if(pstr[0] == 0)
{
break;
}
pstr++;
}
pstr++;
if ((!strcmp(pstr,"flv") || !strcmp(pstr,"avi") || !strcmp(pstr,"rmvb") || !strcmp(pstr,"rm")) && pstr[0] != '\\0')
{
sprintf(filepath, "%s/%s", pdirpath, pp->d_name);
printf("%s\\n", filepath);
}
if (pp->d_type == DT_DIR)
{
Listdir(filepath);
}
}

closedir(dp);

return;
}

int main(void)
{
char dirpath[256] = {0};

printf("请输入目录路径:\\n");
gets(dirpath);

Listdir(dirpath);

return 0;
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » Linux软件编程: 进程解析
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!