更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。
物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机领域.https://blog.csdn.net/weixin_39804904?type=blog
上午: 消息队列
下午:多人聊天系统
1、命名管道只适合2个进程之间的通信,而消息队列能方便多进程通信。
2、队列通信步骤:
第一步,先用ftok获得key值,(只要prj_id的低八位相同获得key相同)
第二步,利用msgget获得队列ID,(如果不存在就创建,存在就打开这个队列)
第三步,利用typedef struct _msg{
long mtype; //类型自己定义,通信双方约定类型
...... //通信内容
}MSG
创建要通信的内容和类型。
第四步,利用msgsnd发送信息。
第五步,利用msgrcv接受信息。
第六步,删掉队列。
获得key值,key_t ftok(const char *pathname,int proj_id);
pathname:路径名(指明key的路径)
proj_id:项目ID,非0整数(只有低8位有效)
返回值:
成功返回key值,失败返回 -1。
创建消息队列:
#include
int msgget(key_t key, int msgflg);
功能:
创建一个新的或打开一个已经存在的消息队列。不同的进程调用此函数,只要用相同的key值就能得到同一个消息队列的ID。
参数:
key:IPC键值
msgflg:标识函数的行为:(一般都是IPC_CREAT)
IPC_CREAT(创建)
IPC_EXCL(如果已经存在则返回失败)。
返回值:
成功:消息队列的标识符,失败:返回-1。
创建一个结构体,其中第一个结构体中的元素为long型,后面的随便,
typedef struct _msg{
long mtype; /*消息类型*/根据消息类型来识别通信
char mtext[100]; /*消息正文*/
}MSG;
int msgsnd(int msqid, const void *msgp,size_t msgsz, int msgflg);
功能:
将新消息添加到消息队列。
参数:
msqid:消息队列的队列ID 即:msgget的返回队列号
msgp:指向待发送消息结构体的指针 即:&MSG
msgsz:消息的字节数
msgflg:IPC_NOWAIT: 若消息没有立即发送则调用该函数的进程会立即返回
0:msgsnd调用阻塞直到条件满足为止
返回值:成功:0;失败:返回-1。
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz, long msgtyp, int msgflg);
功能:
从ID为msqid的消息队列中接收一个消息。一旦接收消息成功,则消息在消息队列中被删除。
参数:
msqid:消息队列的ID,代表要从哪个消息列中获取消息。
msgp: 取出消息的存储地址。
msgsz:消息正文的字节数。
long msgtyp:
msgtyp = 0:返回队列中的第一个消息。
msgtyp > 0:返回队列中消息类型为msgtyp的消息。
msgtyp < 0:返回队列中消息类型值小于或等于msgtyp绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。
注意:
若消息队列中有多种类型的消息,msgrcv获取消息的时候按消息类型获取,不是先进先出的。如果队列中有多条相同类型的消息,在获取该类型消息的时候,先获取最先添加的消息,即先进先出原则。
msgflg:
MSG_NOERROR:若返回的消息比nbytes字节多,则消息就会截短到nbytes字节,且不通知消息发送进程。
IPC_NOWAIT:调用进程会立即返回。若没有收到消息则立即返回-1。
0:msgrcv调用阻塞直到发送消息成功为止。
返回值:成功返回读取消息的长度,失败返回-1。
int msgctl(int msqid, int cmd,struct msqid_ds *buf);
功能:
对消息队列进行各种控制,如修改消息队列的属性,或删除消息消息队列参数:
msqid:消息队列的ID
cmd:函数功能的控制
IPC_STAT:将msqid相关的数据结构中各个元素的当前值存入到由buf指向的结构中。
IPC_SET:将msqid相关的数据结构中的元素设置为由buf指向的结构中的对应值。
IPC_RMID:删除由msqid指示的消息队列,将它从系统中删除并破坏相关数据结构。
buf:msqid_ds数据类型的地址,用来存放或更改消息队列的属性。
返回值:成功:返回 0;失败:返回 -1
3、共享内存通信步骤:
第一步,先用ftok获得key值,(只要prj_id的低八位相同获得key相同)
第二步,利用shmget获得队列ID,(如果不存在就创建,存在就打开这个队列)
第三步,shmat函数映射,得到内存首地址
第四步,利用首地址可以操作内存空间
第五步,删掉共享内存。
4、管道、队列和共享内存的区别:
管道:一般用于二个进程之间的通信,一般是半双工模式
队列:通信主要依据于数据类型,可以多人通信,只要设置好队列ID和数据类型
共享内存:主要申请一个公共空间,每人都能去操作。