嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第五天-Linux消息共享内存(物联技术666)

 更多配套资料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和数据类型

共享内存:主要申请一个公共空间,每人都能去操作。

你可能感兴趣的:(嵌入式培训笔记,笔记,linux,运维,单片机,c语言,服务器)