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;
}
网硕互联帮助中心





评论前必须登录!
注册