文章试读
|
不拘一个遍程序系列:编程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国。一、二、三、四
职场规划:一些杂七杂八的职场感悟吧。不值钱的软件人才 精力充沛与事业成功 让系分来得更猛烈些吧 不值钱的系统分析师
我的诗歌:都是我的打油诗,但是很值得一读。不要工作还衣食无忧之四难歌 香格里拉美人图
宝宝图片:超可爱的小宝宝 写博客
考试培训:主要是关于考研、软考和等级的相关题解。2009考研试题分析 2008年12月程序员试题分析 2009年软考备考全攻略 2008年5月程序员试题解析
|
《精通Unix下C语言编程与项目实践》之八
消息队列发送模型
作者:朱云翔,胡平
12.4.2 消息队列发送模型
本处设计一个小例子描述发送消息的实际步骤,本例要求以阻塞方式向消息队列(关键字为
KEY
)中写入字符串“
Hello Unix!
”,消息类型为
TYPE
。
全部过程共分为
5
个步骤:
1. 定义消息结构
参照代码
12-4
,定义以下消息结构:
struct msgbuf
{
long mtype; /*
消息类型
*/
char ctext[100]; /*
消息数据
*/
};
2. 打开(创建)消息队列
int msgid;
msgid = msgget(KEY, 0666|IPC_CREAT);
if (msgid < 0)
打开(创建消息失败)
如果
msgid
值非负,表示打开(或创建)消息队列成功。
3. 组装消息
设置消息类型和拷贝消息数据:
struct msgbuf buf; /*
申请消息缓冲
*/
buf.mtype = 100; /*
设置消息类型
*/
strcpy(buf.ctext, "HELLO Unix!"); /*
拷贝消息数据
*/
4. 发送消息
万事俱备,只欠东风,调用函数
msgsnd
完成消息发送:
int ret;
ret = msgsnd(msgid, &msg, strlen(msg.ctext), 0);
注意,参数
msgsz
只是消息数据的长度,不包含消息类型长度。
5. 发送判断
在计算机程序设计中,售后处理非常重要,如下所示:
if (ret == -1)
{
if (errno == EINTR)
信号中断,重新发送;
else
系统错误
}
进程在发送消息过程中如果接收到信号,将中止消息发送并返回
EINTR
错误,此时重新发送即可。
实例
本处设计一个消息发送的例子,它循环读取键盘输入,并将输入的字符串信息写入到消息队列
(
关键字为
0x1234)
中,如代码
12-6
所示:
代码
12-6
消息发送程序(节自
/code/chapter12/msg1.c
)
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/errno.h>
extern int errno;
struct mymsgbuf /*
定义消息结构
*/
{
long mtype; /*
消息类型
*/
char ctext[100]; /*
消息数据
*/
};
void main()
{
struct mymsgbuf buf; /*
申请消息缓冲
*/
int msgid;
/*
打开(或创建)消息队列
*/
if ((msgid = msgget(0x1234, 0666|IPC_CREAT)) < 0)
{
fprintf(stderr, "open msg %X failed.\n", 0x1234);
return ;
}
while (strncmp(buf.ctext, "exit", 4))
{
memset(&buf, 0, sizeof(buf));
/*
从键盘输入消息数据内容
*/
fgets(buf.ctext, sizeof(buf.ctext), stdin);
/*
设置消息类型为进程
ID */
buf.mtype = getpid();
/*
发送消息
*/
while ((msgsnd(msgid, &buf, strlen(buf.ctext), 0)) < 0)
{
if (errno == EINTR) continue; /*
信号中断,重新发送
*/
return;
}
}
}
编译和运行代码
12-6
:
# make msg1
cc -O -o msg1 msg1.c
# ./msg1
Please input:Hello World!
Please input:Hello Every Body!
Please input:
读者朋友们,你们好!
Please input:exit
函数
strncmp
对字符串大小进行判断,当两个字符串参数完全相等时返回
0
,否则返回其它值。
程序调用
fgets
直接使用消息数据缓冲区存储输入,请确保输入字符串不要超过最大缓冲区限制,即本例中定义的
99
个字符(最后一个存储
ASCII
码的“
0
”)
,
当用户输入
“
exit
”
时程序结束。上例中共发送了
4
条消息。
执行
ipcs
命令查询消息发送信息:
# ipcs -a -q
T ID KEY MODE OWNER GROUP CREATOR CGROUP CBYTES QNUM QBYTES LSPID LRPID STIME RTIME CTIME
Message Queues:
q 162 0x00001234 --rw-rw-rw- root sys root sys 57 4 65532 1285 0 12:08:45 no-entry 12:08:28
如上所示,
CBYTES
值为
57
,
QNUM
值为
4
,代表我们成功的写入了
4
条消息共
57
个字符信息。请确保执行程序
msg1
前消息队列
0x1234
不存在,或队列为空,否则显示的结果将不一致。
相关文章:
封面 前言 目录 策划 作者
动态库 变长参数 文件锁 外设 僵死进程
定时器 I/O重定向 消息队列