一起talk C栗子吧(第九十七回:C语言实例--使用消息队列进行进程间通信一)
2016-01-11 23:00
543 查看
各位看官们,大家好,上一回中咱们说的是使用共享内存进行进程间通信的例子,这一回咱们说的例子是:使用消息队列进行进程间通信。闲话休提,言归正转。让我们一起talk C栗子吧!
消息队列是SystemV IPC结构这种抽象概念的一种具体对象,这点和共享内存一样。消息队列提供了一个队列供不同的进程使用,进程之间可以通过该队列传递数据,进而实现进程间的通信。
在介绍消息队列的使用方法之前,我们先介绍几个函数,这些函数都是用来操作消息队列的。
该函数用来创建一个新的消息队列或者获取已经存在的消息队列。
第一个参数是键值,通过它来操作IPC在内核中的结构,也就是消息队列在内核中的结构;(前面章回中介绍过)
第二个参数是消息队列的权限标记,该权限和文件权限一样;
该函数运行成功时返回消息队列标识符,否则返回-1;我们可以通过该标识符使用消息队列;
该函数用来把消息添加到消息队列中,这样进程就可以从消息队列中获取消息了;
在使用该函数的时候,我们需要自己定义一个消息的类型,并且计算出该类型的内存空间。消息的类型可以依据程序需要来定义,常见的是定义一个结构体类型。不过类型中的第一个成员必须是一个long int类型的成员,该成员用来确定消息的类型。
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个指针,该指针指向准备添加到消息队列中消息;
第三个参数是一个int类型的值,表示准备添加到消息队列中消息的大小;
第四个参数是一个位标记,该标记用来控制消息队列已满或者达到系统限制时的动作。
该函数运行成功时返回0,否则返回-1;
在使用该函数的时候,第四个参数通常为IPC_NOWAIT,表示消息队列已满后函数不发消息到消息队列中,并且立刻返回-1.如果没有设置该标记,那么消息队列已满后先把以送消息的进程挂起,直到消息到消息队列中有空间了,它再发送消息到消息队列中。
该函数用来从消息队列中获取消息或者说接收消息;
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个指针,该指针指向准备从消息队列中获取的消息;
第三个参数是一个int类型的值,表示获取消息的大小;
第四个参数是一个long int类型的值,表示接收消息的优先级;
第五个参数是一个位标记,该标记用来控制消息队列中没有消息供接收时的动作。
该函数运行成功时返回接收到消息的字节数,否则返回-1;
在使用该函数数,第五个参数的值和msgsnd函数中第四个参数的值一样,而且函数的动作也类似,只不过从发送消息转换为接收消息。该函数的第四个参数通常为0,表示按照消息的发送顺序接收消息;
如果它的值为n(n>0),表示接收类型值为n的这一类消息;
如果它的值为-n(n>0),表示接收类型值为等于或者小于n的这一类消息;
这里说的类型值就是我们定义消息类型中的第一个成员。
该函数用来对消息队列进行相关操作,常用的操作是删除消息队列;
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个命令,表示对消息队列的操作,只有三个命令供使用:IPC_STAT,IPC_SET和IPC_RMID;
第三个参数是一个结构体指针,该结构体中有消息队列的权限和所有者等信息;
该函数运行成功时返回0,否则返回-1;
我们通常使用该函数删除消息队列,这时候需要给第二个参数赋值为IPC_RMID,表示删除消息队列,第三参数可以为空指针。第二个参数的另外两个命令:IPC_STAT表示把第三个参数中的内容和消息队列关联起来;IPC_SET表示把第三个参数中的内容设置为消息队列的值。第三个参数的类型,我们在前面章回中提起过,它和SystemV IPC的结构类似,除了必须有的成员外,它还有自己特有的成员。
该函数的用法和咱们在前面章回中介绍过的shmctl函数用法类似,大家可以进行对比。
我从源代码中找到了第三个参数的类型,详细的定义如下:(位于linux-4.0.3/include/linux/msg.h文件中)
各位看官,关于使用消息队列进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
消息队列是SystemV IPC结构这种抽象概念的一种具体对象,这点和共享内存一样。消息队列提供了一个队列供不同的进程使用,进程之间可以通过该队列传递数据,进而实现进程间的通信。
在介绍消息队列的使用方法之前,我们先介绍几个函数,这些函数都是用来操作消息队列的。
msgget函数
[code]int msgget(key_t key,int msgflag)
该函数用来创建一个新的消息队列或者获取已经存在的消息队列。
第一个参数是键值,通过它来操作IPC在内核中的结构,也就是消息队列在内核中的结构;(前面章回中介绍过)
第二个参数是消息队列的权限标记,该权限和文件权限一样;
该函数运行成功时返回消息队列标识符,否则返回-1;我们可以通过该标识符使用消息队列;
msgsnd函数
[code]int msgsnd(int msg_id, const void *msg_ptr,size_t msg_sz,int msgflg)
该函数用来把消息添加到消息队列中,这样进程就可以从消息队列中获取消息了;
在使用该函数的时候,我们需要自己定义一个消息的类型,并且计算出该类型的内存空间。消息的类型可以依据程序需要来定义,常见的是定义一个结构体类型。不过类型中的第一个成员必须是一个long int类型的成员,该成员用来确定消息的类型。
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个指针,该指针指向准备添加到消息队列中消息;
第三个参数是一个int类型的值,表示准备添加到消息队列中消息的大小;
第四个参数是一个位标记,该标记用来控制消息队列已满或者达到系统限制时的动作。
该函数运行成功时返回0,否则返回-1;
在使用该函数的时候,第四个参数通常为IPC_NOWAIT,表示消息队列已满后函数不发消息到消息队列中,并且立刻返回-1.如果没有设置该标记,那么消息队列已满后先把以送消息的进程挂起,直到消息到消息队列中有空间了,它再发送消息到消息队列中。
msgrcv函数
[code]int msgrcv(int msgid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflg)
该函数用来从消息队列中获取消息或者说接收消息;
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个指针,该指针指向准备从消息队列中获取的消息;
第三个参数是一个int类型的值,表示获取消息的大小;
第四个参数是一个long int类型的值,表示接收消息的优先级;
第五个参数是一个位标记,该标记用来控制消息队列中没有消息供接收时的动作。
该函数运行成功时返回接收到消息的字节数,否则返回-1;
在使用该函数数,第五个参数的值和msgsnd函数中第四个参数的值一样,而且函数的动作也类似,只不过从发送消息转换为接收消息。该函数的第四个参数通常为0,表示按照消息的发送顺序接收消息;
如果它的值为n(n>0),表示接收类型值为n的这一类消息;
如果它的值为-n(n>0),表示接收类型值为等于或者小于n的这一类消息;
这里说的类型值就是我们定义消息类型中的第一个成员。
msgctl函数
[code]int msgctl(int msg_id, int cmd,struct msgid_ds *buf)
该函数用来对消息队列进行相关操作,常用的操作是删除消息队列;
第一个参数是消息队列的标识符,通过msgget函数可以获得;
第二个参数是一个命令,表示对消息队列的操作,只有三个命令供使用:IPC_STAT,IPC_SET和IPC_RMID;
第三个参数是一个结构体指针,该结构体中有消息队列的权限和所有者等信息;
该函数运行成功时返回0,否则返回-1;
我们通常使用该函数删除消息队列,这时候需要给第二个参数赋值为IPC_RMID,表示删除消息队列,第三参数可以为空指针。第二个参数的另外两个命令:IPC_STAT表示把第三个参数中的内容和消息队列关联起来;IPC_SET表示把第三个参数中的内容设置为消息队列的值。第三个参数的类型,我们在前面章回中提起过,它和SystemV IPC的结构类似,除了必须有的成员外,它还有自己特有的成员。
该函数的用法和咱们在前面章回中介绍过的shmctl函数用法类似,大家可以进行对比。
我从源代码中找到了第三个参数的类型,详细的定义如下:(位于linux-4.0.3/include/linux/msg.h文件中)
[code]struct msg_queue { struct kern_ipc_perm q_perm; time_t q_stime; /* last msgsnd time */ time_t q_rtime; /* last msgrcv time */ time_t q_ctime; /* last change time */ unsigned long q_cbytes; /* current number of bytes on queue */ unsigned long q_qnum; /* number of messages in queue */ unsigned long q_qbytes; /* max number of bytes on queue */ pid_t q_lspid; /* pid of last msgsnd */ pid_t q_lrpid; /* last receive pid */ struct list_head q_messages; struct list_head q_receivers; struct list_head q_senders; };
各位看官,关于使用消息队列进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
相关文章推荐
- c语言中的指针基础
- Leetcode 17 - Letter Combinations of a Phone Number
- c++使用dlsym
- C++ 讲解:类结构
- c++ g++运行出现Enable multithreading to use std::thread: Operation not permitted解决
- C++刷新缓冲区
- 深入C++的new
- C++ 讲解:多态
- C++中预处理(条件编译)
- C++开发人脸性别识别教程(9)——搭建MFC框架之显示图片
- 重学C++ (三) 表达式
- C/C++基础试题 测试
- C++中预处理(文件包含include)
- [转]C++中关于new和delete的使用
- 三角形面积计算器--C语言
- C++中宏的定义与用法(现已被内联函数所代替)
- C++中宏和函数的区别
- 【银行家算法】操作系统课程设计
- C++中vector向量的用法(自整)
- C++中四种类型转换方式