您的位置:首页 > 编程语言 > C语言/C++

一起talk C栗子吧(第九十七回:C语言实例--使用消息队列进行进程间通信一)

2016-01-11 23:00 543 查看
各位看官们,大家好,上一回中咱们说的是使用共享内存进行进程间通信的例子,这一回咱们说的例子是:使用消息队列进行进程间通信。闲话休提,言归正转。让我们一起talk C栗子吧!

消息队列是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;
};


各位看官,关于使用消息队列进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: