news 2026/6/26 3:17:04

Linux学习笔记3:进程和进程间通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux学习笔记3:进程和进程间通信

1. 引言

今日继续:进程管理进程间通信(IPC)。理解进程如何创建、调度以及彼此之间如何传递数据,是编写高效 Shell 脚本和系统编程的基础。

2. 进程是什么

简单说,程序是存放在磁盘上的静态文件,进程是程序在内存中运行的实例。每个进程拥有独立的地址空间、一组系统资源,并且由内核统一调度。

每个进程都有一个唯一的PID(Process ID)。PID 为 1 的是 init 或 systemd,是所有用户态进程的祖先。用echo $$可以查看当前 Shell 的 PID。

2.1 进程的创建:fork 与 execl

在 Linux 中,新进程只能通过fork(或 clone)从已有进程复制产生,再用exec 系列函数装载新程序。

fork创建一个与父进程几乎完全相同的子进程,返回两次:

  • 父进程中返回子进程 PID;
  • 子进程中返回 0。
#include<unistd.h>#include<stdio.h>intmain(){pid_tpid=fork();if(pid==0){printf("I am child, PID = %d\n",getpid());}elseif(pid>0){printf("I am parent, child PID = %d\n",pid);}return0;}

fork 之后父子进程并发执行,谁先调度由内核决定。写时复制(Copy-On-Write)技术确保 fork 时只复制页表,真正写入时才分配新内存,因此 fork 速度很快。

exec 系列execlexecvexecleexecveexeclpexecvp)用新程序替换当前进程的地址空间,不创建新进程。调用成功后,原来的代码不再执行;失败则返回 -1。

#include<unistd.h>#include<stdio.h>intmain(){printf("Before exec...\n");execl("/bin/ls","ls","-l",NULL);// 此行仅 exec 失败时才执行perror("execl failed");return1;}

fork + exec 组合是 Linux 创建新进程的标准模式:先 fork 子进程,再在子进程中 exec 新程序,父进程可选择 wait 等待子进程结束。

3. 进程状态与生命周期

Linux 进程在生存期内会在多种状态之间切换,常见的包括:

  • R(运行/可运行)—— 正在 CPU 上执行,或在运行队列中等待。
  • S(可中断睡眠)—— 等待某事件(如 I/O)完成,可被信号唤醒。
  • D(不可中断睡眠)—— 通常在进行硬件 I/O,即使收到信号也不能马上返回。
  • T(停止)—— 被作业控制信号(如 Ctrl+Z)暂停。
  • Z(僵尸)—— 子进程已结束,但父进程尚未回收其退出状态。
  • X(死亡)—— 已回收,彻底消失。

ps auxtop可以看到每个进程的状态标识。

4. 常用进程管理命令

掌握几条基本命令,就能在命令行中实时观察和操作进程。

# 查看所有进程psaux# 实时监控(q 退出)top# 按名称结束进程killallfirefox# 按 PID 发送信号,-9 为强制终止kill-912345# 让进程在后台运行sleep300&# 启动时加 &# 或对已暂停的作业执行bg%1# 查看后台作业jobs# 将后台作业调回前台fg%1# 调整优先级(-20 最高,19 最低)nice-n10./my_programrenice5-p1234

5. 进程间通信概述

多个进程协作时,必须有一种机制来交换数据或同步行为。Linux 提供了丰富的 IPC 方式,从简单的管道到复杂的网络套接字。

6. 管道——最常用的 IPC

6.1 匿名管道

|连接两个命令,前者的标准输出直接成为后者的标准输入,中间不产生临时文件。

ls-l|grep"txt"|wc-l

管道是半双工的,数据只能单向流动。管道的生命周期由两端的进程决定:读端进程退出后写端会收到 SIGPIPE。

6.2 命名管道(FIFO)

匿名管道只能用于父子进程或兄弟进程之间;命名管道有实际的路径名,任意两个进程只要知道路径就可以通信。

# 创建命名管道mkfifomypipe# 终端 1:写入echo"Hello">mypipe# 终端 2:读取catmypipe

7. 消息队列

消息队列由内核维护,允许进程以“消息块”为单位异步交换数据。每条消息有类型标识,接收方可以选择特定类型。

常用命令:

# 查看系统中的消息队列ipcs-q# 删除指定队列(需有权限)ipcrm-q<msqid>

在 C 语言中通过msgget,msgsnd,msgrcv调用。

8. 共享内存

共享内存是最快的 IPC 方式。两个进程将同一块物理内存映射到各自的地址空间,直接读写,无需内核中转。

# 查看共享内存段ipcs-m# 删除共享内存段ipcrm-m<shmid>

编程时常用shmget,shmat,shmdt。为避免竞争,通常搭配信号量使用。

9. 信号——异步通知机制

信号是在软件层面模拟中断的一种机制,用于通知进程发生了某个事件。

常见信号:

信号默认行为说明
SIGINT (2)终止前台进程收到 Ctrl+C
SIGTERM (15)终止kill 默认信号,可被捕获
SIGKILL (9)终止强制杀死,不可捕获
SIGSTOP (19)停止立即暂停进程
SIGCONT (18)继续恢复暂停的进程
SIGCHLD (17)忽略子进程终止时发给父进程

在 Shell 中可以用trap命令捕获信号:

#!/bin/bashcleanup(){echo"清理临时文件..."}trapcleanup SIGINT SIGTERMwhiletrue;dosleep1echo"运行中..."done

10. 套接字——跨网络 IPC

套接字不仅用于网络通信,也可用于本地进程间通信(Unix Domain Socket)。相比 IP 套接字,Unix 域套接字不需要协议栈封装,效率更高。

常见场景:/var/run 下的 .sock 文件,如 Docker 守护进程、MySQL 通过 sock 文件提供服务。

11. 总结

  • 进程是程序在内存中的运行实体,通过 PID 唯一标识。
  • pstopkilljobs是日常管理进程的必备命令。
  • 管道适合简单的数据串联;命名管道解除亲缘限制。
  • 消息队列提供带类型的异步通信。
  • 共享内存速度最快,但需要配套同步机制。
  • 信号用于异步事件通知,trap可在脚本中优雅处理。
  • 套接字将 IPC 延伸至网络,是分布式系统的基础。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 3:15:48

免费获取专业级字体:Montserrat完整使用终极指南

免费获取专业级字体&#xff1a;Montserrat完整使用终极指南 【免费下载链接】Montserrat 项目地址: https://gitcode.com/gh_mirrors/mo/Montserrat 还在为设计项目找不到既专业又好看的字体而烦恼吗&#xff1f;Montserrat字体是设计师们都在悄悄使用的秘密武器——这…

作者头像 李华
网站建设 2026/6/26 3:15:14

一个常用SPSS替代工具的功能梳理

一、简介 SPSSUltra 是一个免安装的统计工具&#xff0c;支持常用分析&#xff08;描述统计、相关、回归、因子/PCA&#xff09;。可上传 Excel/CSV/SPSS 文件&#xff0c;输出表格和图表。当前核心功能免费开放&#xff0c;适合论文写作或业务数据的初步分析。 二、核心功能 …

作者头像 李华
网站建设 2026/6/26 3:11:22

Java CompletableFuture 的异步流设计

Java CompletableFuture的异步流设计&#xff1a;解锁高效并发编程 在现代高并发系统中&#xff0c;异步编程已成为提升性能的关键技术。Java 8引入的CompletableFuture不仅弥补了Future的缺陷&#xff0c;更通过流式API和函数式组合能力&#xff0c;为开发者提供了灵活的异步…

作者头像 李华
网站建设 2026/6/26 3:10:02

代码质量工具静态分析与动态检测

代码质量工具&#xff1a;静态分析与动态检测的双重保障 在软件开发过程中&#xff0c;代码质量直接影响系统的稳定性、安全性和可维护性。为了确保代码的高质量&#xff0c;开发团队通常会借助静态分析&#xff08;Static Analysis&#xff09;和动态检测&#xff08;Dynamic…

作者头像 李华