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


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

消息队列是SystemV IPC结构这种抽象概念的一种具体对象,这点和共享内存一样。消息队列提供了一个队列供不同的进程使用,进程之间可以通过该队列传递数据,进而实现进程间的通信。

在介绍消息队列的使用方法之前,我们先介绍几个函数,这些函数都是用来操作消息队列的。

msgget函数

int msgget(key_t key,int msgflag)

该函数用来创建一个新的消息队列或者获取已经存在的消息队列。

  • 第一个参数是键值,通过它来操作IPC在内核中的结构,也就是消息队列在内核中的结构;(前面章回中介绍过)
  • 第二个参数是消息队列的权限标记,该权限和文件权限一样;
  • 该函数运行成功时返回消息队列标识符,否则返回-1;我们可以通过该标识符使用消息队列;

msgsnd函数

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函数

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函数

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文件中)

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;
};

各位看官,关于使用消息队列进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值