linux多进程消息队列,linuxC多进程通讯---POSIX消息队列

posix与system v对比

•POSIX IPC

•POSIX接口更简单:使用类似于文件I/O的open、close、unlink等接口

•POSIX使用名字代替键来标识IPC对象

•对 IPC 对象引用计数,简化了对 IPC 对象的删除

–跟文件类似,删除操作也仅仅是删除了IPC对象的名字

–只有当IPC对象的引用计数变成0之后才真正销毁IPC对象

•System V IPC

•System V IPC 可移植性更好:几乎所有的UNIX系统都支持system V,POSIX在UNIX系统中只是一个可选组件,有些UNIX系统并不支持

•Linux系统一般都会支持system V

•Linux 2.6开始陆续支持POSIX…

POSIX 编程注意事项

•使用POSIX 消息队列和共享内存时,需要实时库librt链接,编译时需指定 $ -lrt

•使用POSIX 信号量时,需要和线程库libpthread链接起来,编译时需指定$ -lpthread

相关API

•mq_open: 创建或打开一个消息队列

•mq_send: 向消息队列写入一条消息

•mq_receive:从消息队列中读取一条消息

•mq_close: 关闭进程打开的消息队列

•mq_unlink: 删除一个消息队列

•mq_setattr:设置消息队列一些额外的属性

•mq_getattr:获取消息队列一些额外的属性

•mq_nofity: 异步通知

创建或打开 IPC 对象

•函数原型:

–mqd_t mq_open (const char *name, int oflag);

–mqd_t mq_open (const char *name, int oflag, mode_t mode,

struct mq_attr *attr);

•函数功能:

使用指定名字创建或打开一个对象,返回该对象的句柄

•函数参数:

–name:用来标识要创建或打开的对象

–Oflag:O_CREAT/O_EXCL /O_RDONLY /O_WRONLY /O_RDWR /O_NONBLOCK

–Mode:位掩码,权限设置

–Attr:设置消息队列的属性,若为NULL,使用默认属性。Linux3.5以后版本也可通过/proc查看设置

•函数返回值

–成功:返回消息队列的IPC对象描述符

–失败:返回-1,并设置errno

关闭POSIX 消息队列

•函数原型:

int mq_close(mqd_t mqdes);

•函数功能:

通过描述符关闭消息队列

•TIPS:

–POSIX 消息队列在进程终止或执行exec()时会自动被关闭

•删除一个POSIX 消息队列

•函数原型:

int mq_unlink (const char *name);

•函数功能:

–删除通过 name 标识的消息队列

–在所有进程使用完该队列之后销毁该队列。

–若打开该队列的所有进程已经关闭该队列,立即删除

•向 POSIX 消息队列写入消息

•函数原型:

int mq_send(mqd_t mqdes, const char *msg_ptr,

size_t msg_len, unsigned int msg_prio);

•函数功能:

将msg_ptr指向的缓冲区中的消息添加到描述符mqdes所引 用的消息队列中

•函数参数:

–mqdes: 消息队列描述符

–msg_ptr:指向存放消息的缓冲区指针

–msg_len:消息的长度[10,8192]

–msg_prio:消息对队列中按优先级排列,设置为0表示无需优先级

•从 POSIX 消息队列读取消息

•ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);

•函数功能:

–从mqdes引用的消息队列中删除一条优先级最高、存放时间最长的消息

–将删除的消息保存在msg_ptr指针指向的缓冲区

•函数参数:

–mqdes: 消息队列描述符

–msg_ptr:指向存放消息的缓冲区指针

–msg_len:msg_ptr所指向的缓冲区长度,要大于消息队列的mq_msgsize

–msg_prio:如不为空,接收到的消息的优先级会被复制到指针指向处

•函数返回值

–成功:返回接收的消息的字节数

–失败:-1,并设置errno

父子进程通过POSIX消息队列通讯

#include

#include

#include

#include

#include

#include

#define handle_error(msg) \

do{perror(msg);exit(EXIT_FAILURE);}while(0)

int main (void)

{

mqd_t mq_id;

if ((mq_id = mq_open("/posix_msg_queue", O_RDWR | O_CREAT, 0644, NULL)) == -1)

handle_error("mq_open");

struct mq_attr mq_attribute;

if (mq_getattr (mq_id, &mq_attribute) == -1)

handle_error("mq_getattr");

printf ("mq_flags: %ld\n", mq_attribute.mq_flags);

printf ("mq_maxmsg: %ld\n", mq_attribute.mq_maxmsg);

printf ("mq_msgsize: %ld\n", mq_attribute.mq_msgsize);

printf ("mq_curmsgs: %ld\n", mq_attribute.mq_curmsgs);

int ret_from_fork;

ret_from_fork = fork ();

if (ret_from_fork == 0) // child process

{

char msg_buf[mq_attribute.mq_msgsize];

memset (msg_buf, 0, mq_attribute.mq_msgsize);

int count = 0;

while (1)

{

if (mq_receive (mq_id, msg_buf, mq_attribute.mq_msgsize, NULL) == -1)

handle_error("mq_receive");

printf ("child process received msg: %s\n", msg_buf);

sleep (1);

if (++count % 10 == 0)

break;

}

}

else if (ret_from_fork > 0) //parent process

{

int count = 0;

while (1)

{

if (mq_send (mq_id, "hello world", sizeof ("hello world"), 1) == -1)

handle_error("mq_send");

printf ("parent process: send msg to mqueue success\n");

sleep (1);

if (++count % 10 == 0)

break;

}

}

else

handle_error("fork");

mq_close (mq_id);

sleep (5);

if (mq_unlink ("/posix_msg_queue") == -1)

handle_error("mq_unlink");

return 0;

}

两个独立进程通过POSIX消息队列通讯

receive

#include

#include

#include

#include

#include

#include

int main (void)

{

mqd_t mq_id;

if ((mq_id = mq_open("/posix_msg_queue", O_RDONLY | O_CREAT, 0644, NULL)) == -1)

{

perror ("mq_open");

exit (EXIT_FAILURE);

}

struct mq_attr mq_attribute;

if (mq_getattr (mq_id, &mq_attribute) == -1)

{

perror ("mq_getattr");

exit (EXIT_FAILURE);

}

char msg_buf[mq_attribute.mq_msgsize];

memset (msg_buf, 0, mq_attribute.mq_msgsize);

while (1)

{

if (mq_receive (mq_id, msg_buf, mq_attribute.mq_msgsize, NULL) == -1)

{

perror ("mq_receive");

exit (EXIT_FAILURE);

}

printf ("%s\n", msg_buf);

sleep (1);

}

mq_close (mq_id);

if (mq_unlink ("/posix_msg_queue") == -1)

{

perror ("mq_unlink");

exit (EXIT_FAILURE);

}

return 0;

}

send

#include

#include

#include

#include

#include

#include

int main (void)

{

mqd_t mq_id;

if ((mq_id = mq_open("/posix_msg_queue", O_WRONLY | O_CREAT, 0644, NULL)) == -1)

{

perror ("mq_open");

exit (EXIT_FAILURE);

}

while (1)

{

if (mq_send (mq_id, "hello world", sizeof("hello world"), 1) == -1)

{

perror ("mq_receive");

exit (EXIT_FAILURE);

}

printf ("msg send success--------\n");

sleep (1);

}

mq_close (mq_id);

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值