网站网络推广能优化,南宁网站公司, align center ,腾讯云服务器优惠IPC#xff08;进程间通信#xff09;完整笔记一、IPC三大类别1. 传统/古老通信方式无名管道#xff08;pipe#xff09;#xff1a;亲缘关系进程间通信有名管道#xff08;FIFO#xff09;#xff1a;任意进程间通信信号#xff08;signal#xff09;#xff1a;异…IPC进程间通信完整笔记一、IPC三大类别1. 传统/古老通信方式无名管道pipe亲缘关系进程间通信有名管道FIFO任意进程间通信信号signal异步通信方式2. IPC对象通信System V IPC消息队列相对少用共享内存最高效的通信方式信号量集用于进程同步3. Socket通信主要用于网络通信也可用于本地进程通信二、管道通信详解2.1 管道共同特性半双工同一时刻只能单向传输特殊文件不支持定位操作lseek/fseek使用文件IO操作open/read/write/close阻塞特性读端存在写超过64K会阻塞写端存在读空管道会阻塞读端关闭写端会收到SIGPIPE信号写端关闭读端返回0EOF2.2 无名管道pipe创建和使用流程#include unistd.h int pipe(int pipefd[2]); // pipefd[0]:读端, pipefd[1]:写端典型使用模式int fd[2]; pipe(fd); pid_t pid fork(); if (pid 0) { // 父进程 close(fd[0]); // 关闭读端 write(fd[1], data, size); close(fd[1]); } else if (pid 0) { // 子进程 close(fd[1]); // 关闭写端 read(fd[0], buffer, size); close(fd[0]); }关键结论验证存储方式队列结构先进先出FIFO容量限制实际64KBLinux默认同步机制读写端必须同时存在方向固定不能互换读写端2.3 有名管道FIFO创建和使用流程创建管道#include sys/types.h #include sys/stat.h int mkfifo(const char *pathname, mode_t mode); // 例如mkfifo(/tmp/myfifo, 0666);打开管道注意打开方式int fd_read open(fifo_name, O_RDONLY); // 只读方式 int fd_write open(fifo_name, O_WRONLY); // 只写方式 // 不能使用 O_RDWR 或 O_CREAT读写操作// 读端 read(fd_read, buffer, size); // 写端 write(fd_write, data, size);关闭和删除close(fd); unlink(/tmp/myfifo); // 删除管道文件封装函数示例int fifo_read(char *fifoname, void *s, int size) { int fd open(fifoname, O_RDONLY); if (fd 0) return -1; int ret read(fd, s, size); close(fd); return ret; } int fifo_write(char *fifoname, void *s, int size) { int fd open(fifoname, O_WRONLY); if (fd 0) return -1; int ret write(fd, s, size); close(fd); return ret; }重要特性文件系统可见可通过ls查看任意进程访问非亲缘关系进程可通信阻塞特性一端未打开时另一端会在open时阻塞手工操作bash复制 下载# 读管道 cat /tmp/myfifo # 写管道 echo data /tmp/myfifo三、信号通信Signal3.1 信号特点异步通信唯一异步的传统IPC方式中断机制类似硬件中断信号编号1~64其中1~32常用3.2 信号响应方式类型说明不可处理信号Term终止进程SIGKILL(9)Ign忽略信号SIGSTOP(19)Core终止并生成core文件Stop暂停进程Cont继续进程3.3 发送信号kill函数#include sys/types.h #include signal.h int kill(pid_t pid, int sig); // 成功返回0失败返回-1其他发送函数int raise(int sig); // 向自身发信号相当于kill(getpid(), sig) unsigned int alarm(unsigned int seconds); // 定时发送SIGALRM int pause(void); // 暂停进程等待信号3.4 接收和处理信号信号注册函数// 原形 void (*signal(int signum, void (*handler)(int)))(int); // 简化版使用typedef typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);三种处理方式// 1. 默认处理 signal(SIGINT, SIG_DFL); // 2. 忽略处理 signal(SIGINT, SIG_IGN); // 3. 自定义处理 void my_handler(int sig) { printf(Received signal: %d\n, sig); } signal(SIGINT, my_handler);3.5 重要结论不可屏蔽信号SIGKILL(9)强制终止不能忽略/自定义SIGSTOP(19)强制暂停不能忽略/自定义用户自定义信号SIGUSR1(10)用户自定义信号1SIGUSR2(12)用户自定义信号2信号列表部分常用SIGHUP(1) 终端挂起 SIGINT(2) 中断CtrlC SIGQUIT(3) 退出Ctrl\ SIGILL(4) 非法指令 SIGTRAP(5) 跟踪陷阱 SIGABRT(6) 异常终止 SIGBUS(7) 总线错误 SIGFPE(8) 算术异常 SIGKILL(9) 强制终止 SIGUSR1(10) 用户信号1 SIGSEGV(11) 段错误 SIGUSR2(12) 用户信号2 SIGPIPE(13) 管道破裂 SIGALRM(14) 闹钟信号 SIGTERM(15) 终止信号 SIGCHLD(17) 子进程状态改变 SIGCONT(18) 继续执行 SIGSTOP(19) 暂停进程 SIGTSTP(20) 终端暂停CtrlZ四、练习题和实验要点4.1 无名管道实验验证读写端父子进程是否都有fd[0]/fd[1]测试存储结构验证FIFO特性容量测试测试管道最大容量同步验证测试读写阻塞情况双向通信使用两个管道实现双向通信4.2 有名管道实验进程通信A程序发送B程序接收退出机制收到quit双方退出管理工具实现fifo_tool创建/删除管道封装函数实现fifo_read/fifo_write4.3 信号实验自定义kill程序模拟系统kill命令信号响应测试测试所有32个信号响应自定义处理实现信号自定义处理函数五、实用技巧和注意事项5.1 管道使用技巧双向通信使用两个管道一个读一个写进程同步利用管道的阻塞特性错误处理检查read/write返回值资源清理及时关闭管道文件描述符5.2 信号使用技巧信号重入信号处理函数应为可重入函数信号屏蔽使用sigprocmask屏蔽不需要的信号信号队列实时信号可排队标准信号可能丢失竞态条件注意信号处理时的竞态问题5.3 调试技巧管道调试strace -e traceread,write,pipe,close ./program信号调试strace -e tracesignal,kill ./program查看进程信号ps -eo pid,cmd | grep program kill -l # 查看信号列表