//信号 通知进程产生了某个事件 软中断
//SIGINT 该信号由ctrl+c产生信号 功能是终端中断
//SIG_IGN 忽略该信号
//SIG_DFL 恢复默认行为
//signal(修改的信号值,修改后的行为) 替换信号功能
//发送信号 kill()
//kill()可以
// int kill(发送文件的文件名, 发送的信息)
//如果有 int 一般用 if(kill()==-1) 如果==-1就发送失败
//进程间的通信
// 管道
// 特性
//1 管道是单向的 数据只能从左到右
//2 管道会创建子进程来执行命令
//3 管道中的命令是并行执行的
//4 管道可以串联 形成管道涟
//1 有名管道 通过mkfifo命令创建有名管道
//特性
//1 有可见的文件名(存在于文件系统中)
//2 可以被任意进程访问
//3 数据传输遵循先进先出原则
//4 本质是内存中的特殊文件 不占用磁盘空间
//5 关闭所有引用他的进程后 管道文件依然存在(需要手动删除)
//测试1 在命令行输入
// 读端 持续监听管道 cat < 管道文件 持续读取 while true ; do cat < 管道文件 ; done
// 写段 持续接受读端数据 cat > 管道文件
//测试2 在文件写入和读取
// 读端 使用read函数读文件 read文件的第三个参数不能是初始化的strlen
// 写端 使用write函数写数据到管道文件中
//2 无名管道 无名称 仅通过文件描述符访问
//1特性
// 1 仅支持亲缘进程 父子 兄弟
// 2 创建方式 : pipe()系统调用
// 3 生命周期 随进程的结束而销毁
//区别 有名管道 无名管道
//名称 在文件系统中 不在文件系统中
//进程的关系 任意进程(有权限) 父子 兄弟
//生命周期 随文件系统的销毁而销毁 随进程的销毁而销毁
//创建方式 mkfifo pipe
//注意事项
//1 避免管道破裂 其中一端已关闭的情况下 另外一端还在输出数据 会触发SIGPIPE信号 终止写段进程
//2 数据无边界 管道是字节流数据 若按照消息的格式 一条一条发送 需要自定义信息格式(长度+数据) 避免多读少读
//3 缓冲区的阻塞问题 读空 写满会阻塞进程 所以需要fcntl()设置属性进程处理
//4 资源泄露问题 进程退出时关闭管道描述符 会导致缓冲区中的数据丢失
//共享内存
// ipc 进制 进程间通信的信息 ipcs 可以看共享内存的内容
//假设AB两个进程
//单工 : 单向性 确定通信方向后固定,不能相互传输数据
//全双工 : 双向性 同一时刻,两方可以互相传输数据
//半双工 : 双向性 同一时刻,只能一方给另一方传输数据管道的通信方式为半双工
//进程间的通信方式(PIC) : 管道共享内存消息队列信号量 套接字
//int shmget(key_t key, size_t size, int shmflg);
//shmget函数:创建一块共享内存空间
//key:共享内存段的唯一标识
//size:表示创建的共享内存空间的大小
//该函数的返回值 - 1 : 表示共享内存创建失败
//如果是正数,表示该段的标识符
//创建新共享空间时,该参数填正整数
//获取已有共享空间时,该参数可以填0
//shmflg : 标志位,用来控制函数行为
//创建标志 : IPC_CREAT:如果key不存在,则创建
//IPC_EXCL : 与IPC_CREAT配合使用,如果key已经创建则报错并设置错误原因给errno
//权限控制:需要指定权限位(0666 07770600)ipcs : 可以查看当前系统中进程间通信资源
//void* shmat(int shm_id, const void* shm_addr, int shmflg);
//shmat函数作用:将一个已存在的共享内存段映射到进程的地址空间中
//shm_id:共享内存段的标识符,通常是shmget函数的返回值
//shm_addr : 指定共享内存段要附加到进程地址空间的哪个地址
// NULL:让系统内核自动选择一块合适的,未使用的地址来附加共享内存段非NULL(填具体地址) : 系统会将共享内存段附加到指定位置,如果指定位置不能使用,则报错,附加失败shmflg : 控制附加操作标志位
//0 : 默认权限,根据shmget创建时的权限进行读写
//SHM_RDONLY : 以只读方式附加共享内存段,如果该进程尝试写入,则引发段错误
//SHM_EXEC : 允许在共享内存段上执行代码