news 2026/3/2 6:18:17

复习——进程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
复习——进程

进程相关知识点

1. 进程的含义

进程是一个正在执行的程序实例,是操作系统进行资源分配和调度的基本单位。

关键点

  • PCB(Process Control Block):进程控制块,Linux中实现为task_struct结构体

  • 包含信息

    • PID(进程标识符)

    • 当前工作路径(可通过chdir改变)

    • umask(文件创建掩码,默认0002)

    • 进程打开的文件列表

    • 信号处理设置

    • 用户ID、组ID

    • 进程资源上限(ulimit -a查看)

2. 进程与程序的区别

程序进程
静态的代码和数据集合动态的执行过程
存储在硬盘中存在于内存中
永久存在暂时存在
无状态变化有状态变化(创建、运行、终止)
无并发性可以并发执行
-竞争计算机资源

关系

  • 一个程序可运行多次→多个进程

  • 一个进程可运行一个或多个程序

3. 进程的内存分布

0-3GB:用户空间(进程私有) 3-4GB:内核空间(所有进程共享)
  • 使用虚拟地址空间,通过MMU映射到物理内存

  • 1页 = 4KB

4. 进程状态

基本三态

  1. 就绪态运行态阻塞态

Linux扩展状态

  • R:运行态(运行或就绪)

  • S:可中断睡眠态(等待事件)

  • D:不可中断睡眠态(等待I/O)

  • T:停止态(暂停)

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

  • X:结束态

5. 进程调度与上下文切换

  • 内核核心功能:进程调度

  • 调度算法:RR(时间片轮转)、FIFO等

  • 宏观并行:多个进程"同时"运行

  • 微观串行:单个CPU同一时间只执行一个进程

  • 上下文切换:保存当前进程状态,恢复另一进程状态

6. 进程相关命令

# 1. 查看进程信息 ps aux ps -ef # 2. 动态查看进程 top htop # 3. 终止进程 kill -信号 PID killall -信号 进程名 # 常用信号 kill -2 PID # SIGINT(中断,同Ctrl+C) kill -15 PID # SIGTERM(终止,默认) kill -9 PID # SIGKILL(强制终止)

7. 进程创建(fork)

#include <unistd.h> pid_t fork(void);

特点

  • 一次调用,两次返回

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

  • 子进程返回0

  • 失败返回-1

子进程继承

  • 父进程的0-3G用户空间副本

  • 父进程的PCB副本(PID不同)

  • 文件描述符表

  • 从fork()后开始执行

示例

// 一次fork生成2个进程(父子关系) fork(); // 两次fork生成4个进程 fork(); // 生成父子2个进程 fork(); // 每个进程再fork,共4个 // 关系:父子、兄弟关系

8. 获取进程信息

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

9. 进程终止方式

正常终止

  1. main()return

  2. exit():C库函数,刷新缓冲区,执行清理函数

  3. _exit()/_Exit():系统调用,不刷新缓冲区

  4. 最后一个线程从main返回

  5. 最后一个线程调用pthread_exit()

异常终止

  1. abort():产生SIGABRT信号

  2. 收到终止信号(如kill

  3. 最后一个线程被取消

10. exit函数与状态回收

#include <stdlib.h> void exit(int status); // 库函数 void _exit(int status); // 系统调用 // 注册退出处理函数 int atexit(void (*function)(void));

11. 僵尸进程与孤儿进程

  • 僵尸进程:子进程终止,父进程未回收(wait)

  • 孤儿进程:父进程终止,子进程被init进程收养

12. 进程资源回收

#include <sys/wait.h> // 阻塞等待任意子进程 pid_t wait(int *status); // 更灵活的等待 pid_t waitpid(pid_t pid, int *status, int options);

status处理宏

WIFEXITED(status) // 是否正常退出 WEXITSTATUS(status) // 获取退出状态 WIFSIGNALED(status) // 是否因信号终止 WTERMSIG(status) // 获取终止信号

waitpid参数

  • pid = -1:等待任意子进程(同wait)

  • pid > 0:等待指定PID子进程

  • pid = 0:等待同进程组的子进程

  • pid < -1:等待指定进程组的子进程

  • options = 0:阻塞

  • options = WNOHANG:非阻塞

13. exec函数族

功能:用新程序替换当前进程映像

六种变体

int execl(const char *path, const char *arg, ..., NULL); int execv(const char *path, char *const argv[]); int execle(const char *path, const char *arg, ..., char *const envp[]); int execve(const char *path, char *const argv[], char *const envp[]); int execlp(const char *file, const char *arg, ..., NULL); int execvp(const char *file, char *const argv[]);

区别

  • 带l:参数列表形式(list)

  • 带v:参数数组形式(vector)

  • 带p:使用PATH环境变量查找可执行文件

  • 带e:可传递环境变量数组

示例

// 方式1:参数列表 execl("/bin/ls", "ls", "-l", NULL); // 方式2:参数数组 char *args[] = {"ls", "-l", NULL}; execv("/bin/ls", args); // 方式3:使用PATH查找 execlp("ls", "ls", "-l", NULL);

14. system函数

#include <stdlib.h> int system(const char *command);

内部实现fork() + exec() + wait()

15. 编程练习示例

练习1:父子进程同时写文件

#include <stdio.h> #include <unistd.h> #include <time.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid > 0) { // 父进程 FILE *fp = fopen("1.txt", "a"); for (int i = 0; i < 5; i++) { time_t now = time(NULL); fprintf(fp, "父进程 PID=%d 时间:%s", getpid(), ctime(&now)); fflush(fp); sleep(1); } fclose(fp); wait(NULL); // 等待子进程 } else if (pid == 0) { // 子进程 FILE *fp = fopen("1.txt", "a"); for (int i = 0; i < 5; i++) { time_t now = time(NULL); fprintf(fp, "子进程 PID=%d 时间:%s", getpid(), ctime(&now)); fflush(fp); sleep(1); } fclose(fp); } return 0; }

练习2:waitpid指定回收进程

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> int main() { pid_t pids[3]; for (int i = 0; i < 3; i++) { pids[i] = fork(); if (pids[i] == 0) { sleep(rand() % 3); // 子进程睡眠随机时间 printf("子进程 %d 退出\n", getpid()); exit(i); // 退出状态为i } } // 父进程:指定回收第二个子进程 int status; pid_t ret = waitpid(pids[1], &status, 0); if (ret > 0 && WIFEXITED(status)) { printf("回收进程 %d,退出状态: %d\n", ret, WEXITSTATUS(status)); } // 非阻塞回收其他进程 while (1) { pid_t ret = waitpid(-1, &status, WNOHANG); if (ret > 0) { printf("非阻塞回收进程 %d\n", ret); } else if (ret == 0) { // 还有子进程运行 sleep(1); } else { // 所有子进程已回收 break; } } return 0; }

作业:父子进程文件通信

#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid > 0) { // 父进程:写数据 FILE *fp = fopen("data.txt", "w"); char buf[256]; while (1) { printf("输入内容(quit退出): "); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = '\0'; // 去掉换行符 fprintf(fp, "%s\n", buf); fflush(fp); if (strcmp(buf, "quit") == 0) break; } fclose(fp); wait(NULL); // 等待子进程 } else if (pid == 0) { // 子进程:读数据 sleep(1); // 等待父进程先写 FILE *fp = fopen("data.txt", "r"); char buf[256]; while (1) { if (fgets(buf, sizeof(buf), fp) != NULL) { buf[strlen(buf)-1] = '\0'; printf("子进程读取: %s\n", buf); if (strcmp(buf, "quit") == 0) break; } usleep(100000); // 100ms } fclose(fp); } return 0; }

16.重要概念总结

  1. 并发vs并行

    • 并发:多个进程交替执行(单核)

    • 并行:多个进程同时执行(多核)

  2. 进程分类

    • 交互式进程(shell、编辑器)

    • 批处理进程(shell脚本)

    • 守护进程(后台服务)

  3. 原语操作

    • fork、exec、wait等是不可分割的原子操作

  4. 进程关系

    • 父子进程、兄弟进程

    • 进程组、会话

  5. 资源管理

    • 避免僵尸进程(及时wait)

    • 避免孤儿进程(合理设计进程关系)

    • 文件描述符继承与关闭

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/1 18:01:00

单北斗GNSS变形监测在工程应用中的优势与前景探讨

单北斗GNSS变形监测系统具备高精度和实时性&#xff0c;广泛应用于桥梁、坝体及地质灾害监测。该系统通过卫星定位技术&#xff0c;能够及时获取位移和变形数据&#xff0c;为工程安全提供有力支撑。本文将详细探讨其在不同工程领域的优势&#xff0c;并分析相关的安装及维护指…

作者头像 李华
网站建设 2026/2/20 8:03:10

2026年网络安全就业前景怎么样?好找工作吗?

众所周知&#xff0c;网络安全与我们息息相关&#xff0c;无论是企业还是个人都应该重视网络安全。 而网络安全作为一个新兴行业&#xff0c;人才需求量远大于供给&#xff0c;因此在薪资福利上具有很大的优势&#xff0c;但对于初学者而言&#xff0c;很多人依然担心前景问题&…

作者头像 李华
网站建设 2026/2/6 19:04:38

【工业级自动化测试利器】:Open-AutoGLM抗模糊算法全栈优化方案

第一章&#xff1a;Open-AutoGLM UI 识别抗模糊算法概述Open-AutoGLM 是一款基于视觉大模型的自动化用户界面识别框架&#xff0c;其核心模块之一是抗模糊算法&#xff0c;专门用于提升在低分辨率、运动模糊或高斯噪声干扰下的 UI 元素检测准确率。该算法结合了图像预处理增强与…

作者头像 李华
网站建设 2026/2/5 15:30:47

探索西克编码器调零与读写位置软件那些事儿

西克编码器调零软件&#xff0c;西克编码器读写位置软件&#xff0c;西克SKM36编码器调零软件&#xff0c;SICK编码器调零软件在自动化控制领域&#xff0c;西克编码器扮演着至关重要的角色。无论是精准定位&#xff0c;还是速度监测&#xff0c;编码器的准确数据输出都是系统稳…

作者头像 李华
网站建设 2026/2/28 12:44:22

从数据到决策:Open-AutoGLM如何重构智能家居的调节逻辑?

第一章&#xff1a;从数据到决策&#xff1a;Open-AutoGLM驱动的智能家居新范式在物联网与人工智能深度融合的当下&#xff0c;智能家居系统正从“被动响应”迈向“主动决策”。Open-AutoGLM 作为一款开源的自动化生成语言模型框架&#xff0c;凭借其强大的上下文理解与推理能力…

作者头像 李华
网站建设 2026/2/26 21:47:58

【限时解读】Open-AutoGLM体重变化预警系统:提前14天预判异常波动

第一章&#xff1a;Open-AutoGLM 体重变化追踪在健康监测与个性化医疗场景中&#xff0c;持续追踪用户的体重变化趋势是评估生活方式干预效果的重要手段。Open-AutoGLM 作为一个开源的自动推理框架&#xff0c;能够结合自然语言指令与传感器数据&#xff0c;实现对用户体重数据…

作者头像 李华