1. 进程间通信(IPC)基础概念
1.1 什么是进程间通信
进程间通信(IPC)指两个或多个进程进行信息相互传递的过程。
进程间通信(IPC)基础概念 1.1 什么是进程间通信 进程间通信(IPC)指两个或多个进程进行信息相互传递的过程。 **进程独立性**:每个进程拥有独立的内核数据结构与代码数据空间。 **非 IPC 示例**:父子进程间的全局变量共享仅是 fork() 时的写时复制初始状态,并非双向、持续的通信机制。一个进程崩溃通常不会直接影响另一个进程。 1.2 为什么需要 IPC **数据传输**:进程间传…

进程间通信(IPC)指两个或多个进程进行信息相互传递的过程。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
fork() 时的写时复制初始状态,并非双向、持续的通信机制。一个进程崩溃通常不会直接影响另一个进程。核心前提:让不同的进程看到同一份资源。操作系统必须提供相应的系统调用来创建和管理这份共享资源。
早期 Unix 系统缺乏统一标准,后逐渐形成 System V IPC 标准(包含共享内存、消息队列、信号量)。随着技术发展,POSIX 标准及现代网络通信机制逐渐成为主流,但 System V 的核心思想仍具重要参考价值。
read() 返回 0(EOF)。SIGPIPE 信号,导致写端进程终止。进程池通过父进程预先创建多个子进程,利用管道分发任务。
waitpid() 回收所有子进程,否则会产生僵尸进程。命名管道在文件系统中创建一个特殊文件(类型为 p),使无血缘关系的进程也能通过路径名找到同一份资源。
open() 打开已存在的 FIFO 文件。open() 默认阻塞,直到读写两端均打开该管道。\0,按实际读取字节数处理即可。服务端(写端)
#include <iostream>
#include <cstdio>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char* fifo = "myfifo";
int wfd = open(fifo, O_WRONLY);
if (wfd < 0) {
perror("open");
return 1;
}
std::string msg;
while (std::cin >> msg) {
write(wfd, msg.c_str(), msg.size());
}
close(wfd);
return 0;
}
客户端(读端)
#include <iostream>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
int main() {
const char* fifo = "myfifo";
umask(0);
if (mkfifo(fifo, 0666) == -1 && errno != EEXIST) {
perror("mkfifo");
return 1;
}
int rfd = open(fifo, O_RDONLY);
if (rfd < 0) {
perror("open");
return 2;
}
char buf[1024];
ssize_t n;
while ((n = read(rfd, buf, sizeof(buf) - 1)) > 0) {
buf[n] = '\0';
std::cout << "Received: " << buf << std::endl;
}
close(rfd);
unlink(fifo); // 清理 FIFO 文件
return 0;
}
共享内存是 System V IPC 中速度最快的通信方式。
| 函数 | 作用 | 关键参数说明 |
|---|---|---|
shmget(key, size, flags) | 创建或获取共享内存 | key: 唯一标识(常用 ftok() 生成)flags: IPC_CREAT | IPC_EXCL | 0666 |
shmat(shmid, addr, flags) | 挂接(映射到虚拟地址) | 返回映射后的虚拟地址指针 |
shmdt(addr) | 去关联(解除映射) | 传入 shmat 返回的地址 |
shmctl(shmid, IPC_RMID, NULL) | 删除共享内存 | 标记删除,引用计数为 0 时释放 |
shmctl 删除或使用 ipcrm -m shmid 命令清理。ftok(path, proj_id) 算法,结合文件 inode 和项目 ID 生成唯一 key_t。#ifndef SHM_HPP
#define SHM_HPP
#include <iostream>
#include <string>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <unistd.h>
class Shm {
public:
Shm(int size = 4096) : _shmid(-1), _size(size), _key(0), _addr(nullptr) {}
~Shm() { if (_addr) Detach(); }
bool Create() {
_key = ftok("/tmp", 0x66);
if (_key < 0) { perror("ftok"); return false; }
_shmid = shmget(_key, _size, IPC_CREAT | IPC_EXCL | 0666);
return _shmid >= 0;
}
bool Get() {
_key = ftok("/tmp", 0x66);
if (_key < 0) { perror("ftok"); return false; }
_shmid = shmget(_key, _size, IPC_CREAT);
return _shmid >= 0;
}
void* Attach() {
_addr = shmat(_shmid, nullptr, 0);
return (_addr == (void*)-1) ? nullptr : _addr;
}
void Detach() {
if (_addr) shmdt(_addr);
_addr = nullptr;
}
bool Delete() {
return shmctl(_shmid, IPC_RMID, nullptr) == 0;
}
void PrintInfo() {
struct shmid_ds ds;
shmctl(_shmid, IPC_STAT, &ds);
std::cout << "Key: " << std::hex << ds.shm_perm.__key << std::dec
<< ", Size: " << ds.shm_segsz << " bytes" << std::endl;
}
private:
key_t _key;
int _shmid;
int _size;
void* _addr;
};
#endif