管道和消息队列
提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录一、管道Pipe管道的分类无名管道1.创建方式2.使用方法3.使用管道实现 ps aux | grep bash 指令命名管道1.命名管道的创建2.命名管道的使用二、消息队列Message Queue1.消息队列函数解析ftok() - 键值生成msgget() - 队列创建/获取msgsnd() - 发送消息msgrcv() - 接收消息核心重点msgctl() - 控制操作一、管道Pipe管道是一种Linux中的进程间通信的方式IPC通过在两个进程之间创建一个单向数据通道实现数据传输。管道的分类无名管道特点只能在有亲缘关系的进程间使用父子进程或者兄弟进程。半双工通信数据只能单向流动不能同时向两端输出。基于文件描述符通过pipe函数创建。存在于内存中随进程结束而销毁。1.创建方式intret;intfd[2];//用数组存储数据fd[0]为读端fd[1]为写端。retpipe(fd);//创建匿名管道2.使用方法在父进程中通过fork创建子进程分别在父子进程中实现不同的功能同时在使用时需要关闭不需要的进程。例如为写端时需要closefd[0])关闭读端。3.使用管道实现 ps aux | grep bash 指令//create pipeintfd[2];intretpipe(fd);if(ret-1){printf(failed!\n);exit(1);}pid_tpid;pidfork();//father ps auxif(pid0){close(fd[0]);dup2(fd[1],STDOUT_FILENO);execlp(ps,ps,aux,NULL);//replace father processperror(execlp);exit(0);}//child grep bashelseif(pid0){close(fd[1]);dup2(fd[0],STDIN_FILENO);execlp(grep,grep,bash,NULL);//replace child processperror(execlp);exit(0);}// when fork failed,this command will be excutedprintf(fd[0] is %d,\n,fd[0]);printf(fd[1] is %d,\n,fd[1]);close(fd[0]);close(fd[1]);return0;首先先用一个数组创建管道的读端和写端再用这个数组创建一个匿名管道。再通过fork()函数创建子进程通过execlp函数分别对父子进程分配工作父进程完成ps aux命令通过dup2重定向写入到管道中。而子进程通过重定向从管道中读取数据在执行grep bash筛选出grep找到包含bash的行写入自己的标准输出默认是屏幕。命名管道特点允许无亲缘关系的进程间通信命名管道以文件形式存在于文件系统中半双工通信1.命名管道的创建#includesys/types.h#includesys/stat.hintmkfifo(constchar*pathname,mode_tmode);mkfifo函数需要两个参数一个是管道名一个是文件权限。创建完成后会在文件中显示一个新类型的文件。中间mkfifo即为管道类型的文件文件类型是p开头。intret;retmkfifo(./mymkfifo,0777);if(ret-1){printf(mkfifo failed!\n);return-1;}printf(mkfifo success!\n);上述代码即可创建一个管道文件。2.命名管道的使用要想使用管道需要给管道创建文件描述符。实现read端intfd;intaread;charreadbuf[50]{0};fdopen(./mymkfifo,O_RDONLY);//以只读权限打开管道if(fd-1){//打开失败管道不存在printf(open failed!\n);return-1;}areadread(fd,readbuf,50);//read函数返回读到的字节数printf(read %d byte from fifo:%s.,aread,readbuf);close(fd);return0;实现write端intfd;charstr[128]{0};//存储写的内容fdopen(./mymkfifo,O_WRONLY);//以只写权限打开if(fd-1){printf(open failed!\n);return-1;}fgets(str,sizeof(str),stdin);//put from keyboardwrite(fd,str,strlen(str));//写入close(fd);return0;这样即可实现数据的单向流动。运行一下试试二、消息队列Message Queue消息队列是消息的链表允许多个进程向队列中写入消息或读取消息。1.消息队列函数解析ftok() - 键值生成key_tkey;// 键值key可以用来控制两个进程在同一个消息队列中进行数据操作。/* 常用方式使用当前目录和项目ID */keyftok(.,A);// 使用当前目录和字符A生成键值/* 注意事项 */// 1. path必须存在且可访问// 2. id只使用低8位0-255// 3. 删除文件后重建会得到不同的keymsgget() - 队列创建/获取intmsqid;/* 创建私有队列用于父子进程 */msqidmsgget(IPC_PRIVATE,IPC_CREAT|0666);/* 创建或获取命名队列 */keyftok(/tmp,M);msqidmsgget(key,IPC_CREAT|IPC_EXCL|0666);// 排他性创建/* msgflg标志详解 */#defineIPC_CREAT01000/* 不存在则创建 */#defineIPC_EXCL02000/* 与IPC_CREAT配合排他创建 */#defineIPC_NOWAIT04000/* 非阻塞操作用于后续调用 *//* 权限位类似文件权限 */// 0600 - 所有者读写// 0666 - 所有用户读写msgsnd() - 发送消息structmy_msgbuf{longmtype;chardata[100];}msg;msg.mtype1;// 类型必须 0strcpy(msg.data,Hello World);/* 阻塞发送 */if(msgsnd(msqid,msg,sizeof(msg.data),0)-1){perror(msgsnd);}/* 非阻塞发送 */if(msgsnd(msqid,msg,sizeof(msg.data),IPC_NOWAIT)-1){if(errnoEAGAIN){printf(队列满稍后重试\n);}}/* msgflg标志 */#defineIPC_NOWAIT04000/* 非阻塞操作 */msgrcv() - 接收消息核心重点structmy_msgbufmsg;ssize_trecv_len;/* msgtyp参数详解 - 消息接收规则 */recv_lenmsgrcv(msqid,msg,sizeof(msg.data),msgtyp,msgflg);// msgtyp 0 : 接收队列中第一个消息FIFO// msgtyp 0 : 接收类型等于msgtyp的第一个消息// msgtyp 0 : 接收小于等于|msgtyp|的最小类型值优先级模型/* 实际应用场景 */// 场景1按顺序接收所有消息msgrcv(msqid,msg,size,0,0);// 最简单的FIFO// 场景2只接收特定类型的消息如只处理错误日志msgrcv(msqid,msg,size,2,0);// 只接收类型为2的消息// 场景3实现优先级处理数值越小优先级越高msgrcv(msqid,msg,size,-10,0);// 接收类型1-10中最小类型的消息// 场景4接收任何消息但不阻塞if(msgrcv(msqid,msg,size,0,IPC_NOWAIT)-1){if(errnoENOMSG){printf(队列为空\n);}}/* msgflg标志 */#defineIPC_NOWAIT04000/* 非阻塞 */#defineMSG_NOERROR010000/* 消息过长时截断而非报错 */msgctl() - 控制操作structmsqid_dsbuf;/* cmd命令详解 */// 1. IPC_STAT - 获取队列状态if(msgctl(msqid,IPC_STAT,buf)0){printf(队列中消息数: %ld\n,buf.msg_qnum);printf(队列最大字节: %ld\n,buf.msg_qbytes);printf(最后发送进程: %d\n,buf.msg_lspid);}// 2. IPC_SET - 修改队列属性buf.msg_perm.mode0666;// 修改权限buf.msg_qbytes65536;// 修改队列大小需要特权if(msgctl(msqid,IPC_SET,buf)-1){perror(msgctl IPC_SET);}// 3. IPC_RMID - 删除消息队列if(msgctl(msqid,IPC_RMID,NULL)-1){perror(msgctl IPC_RMID);}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2410391.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!