本文介绍: 第一个参数是路径名,通常是一个已经存在的文件或目录的路径名。在这个例子中,.表示当前目录,也就是代码所在的目录。不同进程能通过消息队列来进行通信,不同进程也能获取或发送特定类型的消息,即选择性的收发消息。第二个参数是一个由用户自定义的字符,用于生成键值。在这里,它是字符 ‘a’。key = ftok(“.”, ‘a’) // 创建键值。
概念:
不同进程能通过消息队列来进行通信,不同进程也能获取或发送特定类型的消息,即选择性的收发消息。
常用函数功能:
struct msgbuf{ // 数据协议
long mtype; // 数据类型,由用户自己定义
char buf[N]; // 数据部分
};
第一个参数是路径名,通常是一个已经存在的文件或目录的路径名。在这个例子中,.表示当前目录,也就是代码所在的目录。
第二个参数是一个由用户自定义的字符,用于生成键值。在这里,它是字符 ‘a’。
这个键值的作用即标识一个消息队列,通过键值识别具体的某条消息队列
代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#define N 128
#define SIZE sizeof(struct msgbuf) - sizeof(long)
#define TYPE1 100
#define TYPE2 200
struct msgbuf{
long mtype;
char buf[N];
};
int main(){
key_t key;
if((key = ftok(".", 'a')) < 0){ // 创建键值
perror("ftok error");
return -1;
}
int msqid;
struct msgbuf msg_snd, msg_rcv; // 发送端接收端
if((msqid = msgget(key, IPC_CREAT|IPC_EXCL|0664)) < 0){ // 创建消息队列 存在则报错 出现错误返回-1
if(errno != EEXIST){ // 若消息不存在
perror("msgget error");
return -1;
}
else{ // 则消息队列存在 直接打开
msqid = msgget(key, 0664);
}
}
pid_t pid;
pid = fork(); // 创建子进程
if(pid < 0){
perror("fork error");
return -1;
}
else if(pid == 0){ // 若是子进程
while(1){
msg_snd.mtype = TYPE1; // 标识信息的符号
fgets(msg_snd.buf, N, stdin); // 标准输入 读取用户输入
msg_snd.buf[strlen(msg_snd.buf) - 1] = ''; // 方便读取
msgsnd(msqid, &msg_snd, SIZE, 0); // 消息无法发送则阻塞直到可发送为止
if(strncmp(msg_snd.buf, "quit", 4) == 0){ // 查看用户输入若为quit 则结束父进程 子进程自我结束
kill(getppid(), SIGKILL);
break;
}
}
}
else{ // 父进程
while(1){
msgrcv(msqid, &msg_rcv, SIZE, TYPE2, 0); // 只接收 TYPE2 直到等到有符合条件的消息为止
if(strncmp(msg_rcv.buf, "quit", 4) == 0){
kill(pid, SIGKILL);
msgctl(msqid, IPC_RMID, NULL); // 删除消息队列
break;
}
printf("msg_b:%sn", msg_rcv.buf);
}
}
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#define N 128
#define SIZE sizeof(struct msgbuf) - sizeof(long)
#define TYPE1 100
#define TYPE2 200
struct msgbuf{
long mtype;
char buf[N];
};
int main(){
key_t key;
if((key = ftok(".", 'a')) < 0){ // 创建键值
perror("ftok error");
return -1;
}
int msqid;
struct msgbuf msg_snd, msg_rcv; // 发送端接收端
if((msqid = msgget(key, IPC_CREAT|IPC_EXCL|0664)) < 0){ // 创建消息队列 存在则报错 出现错误返回-1
if(errno != EEXIST){ // 若消息不存在
perror("msgget error");
return -1;
}
else{ // 则消息队列存在 直接打开
msqid = msgget(key, 0664);
}
}
pid_t pid;
pid = fork(); // 创建子进程
if(pid < 0){
perror("fork error");
return -1;
}
else if(pid == 0){ // 若是子进程 发送方
while(1){
msg_snd.mtype = TYPE2; // 标识信息的符号
fgets(msg_snd.buf, N, stdin); // 标准输入 读取用户输入
msg_snd.buf[strlen(msg_snd.buf) - 1] = ''; // 方便读取
msgsnd(msqid, &msg_snd, SIZE, 0); // 消息无法发送则阻塞直到可发送为止
if(strncmp(msg_snd.buf, "quit", 4) == 0){ // 查看用户输入若为quit 则结束父进程 子进程自我结束
kill(getppid(), SIGKILL);
break;
}
}
}
else{ // 父进程 接受方
while(1){
msgrcv(msqid, &msg_rcv, SIZE, TYPE1, 0); // 只接收 TYPE1 直到等到有符合条件的消息为止
if(strncmp(msg_rcv.buf, "quit", 4) == 0){
kill(pid, SIGKILL);
msgctl(msqid, IPC_RMID, NULL); // 删除消息队列
break;
}
printf("msg_a:%sn", msg_rcv.buf);
}
}
return 0;
}
俩个程序各开一个子进程,父进程。子进程负责发送信息,父进程负责接收信息,最终能实现在不同终端通讯,发送quit终止通讯
效果:
原文地址:https://blog.csdn.net/xyint/article/details/134699308
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_10853.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。