java linux 消息队列_我的第一个Linux程序----利用消息队列来实现IPC

晚上在FC4下调试出了第一个linux程序,成功地运行,有点成就感,虽然这个程序是抄过来.

本程序的功能是利用系统V(Sys V)消息队列来实现进程间的通信(IPC).

简单地介绍程序:

用到的一个数据结构-------消息,用一个结构体来表示:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

struct msgbuf

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

long

mtype;

//

消息的类型

d18c02628675d0a2c816449d98bda930.png

char

mtext[

1

];

//

消息的内容,并不是表示只存一个字符

8f1ba5b45633e9678d1db480c16cae3f.png

}

;

4f1150b881333f12a311ae9ef34da474.png

几个API:

key_t ftok (char*pathname, char proj);

它返回与路径pathname相对应的一个键值。该函数不直接对消息队列操作,但在调用msgget()来获得消息队列描述字前,往往要调用该函数。典型用法   key=ftok('.', 'a');

int msgget(key_t key, int msgflg)     参数key是一个键值,由ftok获得;msgflg参数是一些标志位。该调用返回与健值key相对应的消息队列描述字。

在以下两种情况下,该调用将创建一个新的消息队列:

如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;

key参数为IPC_PRIVATE;

参数msgflg可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。

调用返回:成功返回消息队列描述字,否则返回-1。

int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。

msqid为消息队列描述字;消息返回后存储在msgp指向的地址,msgsz指定msgbuf的mtext成员的长度(即消息内容的长度),msgtyp为请求读取的消息类型;读消息标志msgflg可以为以下几个常值的或:

IPC_NOWAIT 如果没有满足条件的消息,调用立即返回,此时,errno=ENOMSG

IPC_EXCEPT 与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息

IPC_NOERROR 如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将丢失。

msgrcv手册中详细给出了消息类型取不同值时(>0; <0; =0),调用将返回消息队列中的哪个消息。

msgrcv()解除阻塞的条件有三个:

消息队列中有了满足条件的消息;

msqid代表的消息队列被删除;

调用msgrcv()的进程被信号中断;

调用返回:成功返回读出消息的实际字节数,否则返回-1。

int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);

向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。

对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:

当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量;

当前消息队列的消息数(单位"个")不小于消息队列的总容量(单位"字节数"),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节。

msgsnd()解除阻塞的条件有三个:

不满足上述两个条件,即消息队列中有容纳该消息的空间;

msqid代表的消息队列被删除;

调用msgsnd()的进程被信号中断;

调用返回:成功返回0,否则返回-1。

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。

IPC_STAT:该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid结构中;

IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;可设置属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。

IPC_RMID:删除msqid标识的消息队列;

调用返回:成功返回0,否则返回-1。

4f1150b881333f12a311ae9ef34da474.png

#include

<

stdio.h

>

4f1150b881333f12a311ae9ef34da474.png#include

<

stdlib.h

>

4f1150b881333f12a311ae9ef34da474.png#include

<

ctype.h

>

4f1150b881333f12a311ae9ef34da474.png#include

<

sys

/

ipc.h

>

4f1150b881333f12a311ae9ef34da474.png#include

<

sys

/

types.h

>

4f1150b881333f12a311ae9ef34da474.png#include

<

sys

/

msg.h

>

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

#define

MAX_SEND_SIZE 80

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

struct

mymsgbuf

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

long

mtype;

d18c02628675d0a2c816449d98bda930.png

char

mtext[MAX_SEND_SIZE];

8f1ba5b45633e9678d1db480c16cae3f.png}

;

4f1150b881333f12a311ae9ef34da474.png

void

send_message(

int

qid,

struct

mymsgbuf

*

qbuf,

long

type,

char

*

text);

4f1150b881333f12a311ae9ef34da474.png

void

read_message(

int

qid,

struct

mymsgbuf

*

qbuf,

long

type);

4f1150b881333f12a311ae9ef34da474.png

void

remove_queue(

int

qid);

4f1150b881333f12a311ae9ef34da474.png

void

change_queue_mode(

int

qid,

char

*

mode);

4f1150b881333f12a311ae9ef34da474.png

void

usage(

void

);

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

int

main(

int

argc,

char

*

argv[])

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    key_t key;

d18c02628675d0a2c816449d98bda930.png

int

msgqueue_id;

d18c02628675d0a2c816449d98bda930.png

struct

mymsgbuf qbuf;

d18c02628675d0a2c816449d98bda930.png    

d18c02628675d0a2c816449d98bda930.png

if

(

1

==

argc)

d18c02628675d0a2c816449d98bda930.png        usage();

d18c02628675d0a2c816449d98bda930.png    key

=

ftok(

"

.

"

,

'

m

'

);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

if

((msgqueue_id

=

msgget(key,IPC_CREAT

|

0660

))

==-

1

)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png        perror(

"

msgget

"

);

d18c02628675d0a2c816449d98bda930.png        exit(

1

);

ecedf933ec37d714bd4c2545da43add2.png    }

d18c02628675d0a2c816449d98bda930.png

switch

(tolower(argv[

1

][

0

]))

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

case

'

s

'

:send_message(msgqueue_id,(

struct

mymsgbuf

*

)

&

qbuf,

d18c02628675d0a2c816449d98bda930.png                    atol(argv[

2

]),argv[

3

]);

d18c02628675d0a2c816449d98bda930.png

break

;

d18c02628675d0a2c816449d98bda930.png

case

'

r

'

:read_message(msgqueue_id,

&

qbuf,atol(argv[

2

]));

d18c02628675d0a2c816449d98bda930.png

break

;

d18c02628675d0a2c816449d98bda930.png

case

'

d

'

:remove_queue(msgqueue_id);

d18c02628675d0a2c816449d98bda930.png

break

;

d18c02628675d0a2c816449d98bda930.png

case

'

m

'

:change_queue_mode(msgqueue_id,argv[

2

]);

d18c02628675d0a2c816449d98bda930.png

break

;

d18c02628675d0a2c816449d98bda930.png

default

:usage();

ecedf933ec37d714bd4c2545da43add2.png    }

d18c02628675d0a2c816449d98bda930.png

return

0

;

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

void

send_message(

int

qid,

struct

mymsgbuf

*

qbuf,

long

type,

char

*

text)

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    printf(

"

send a message

9b8a8a44dd1c74ae49c20a7cd451974e.png\n

"

);

d18c02628675d0a2c816449d98bda930.png    qbuf

->

mtype

=

type;

d18c02628675d0a2c816449d98bda930.png    strcpy(qbuf

->

mtext,text);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

if

((msgsnd(qid,(

struct

msgbuf

*

)qbuf,strlen(qbuf

->

mtext)

+

1

,

0

))

==-

1

)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png        perror(

"

msgsnd

"

);

d18c02628675d0a2c816449d98bda930.png        exit(

1

);

ecedf933ec37d714bd4c2545da43add2.png    }

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

void

read_message(

int

qid,

struct

mymsgbuf

*

qbuf,

long

type)

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    printf(

"

reading a message

9b8a8a44dd1c74ae49c20a7cd451974e.png.\n

"

);

d18c02628675d0a2c816449d98bda930.png    qbuf

->

mtype

=

type;

d18c02628675d0a2c816449d98bda930.png    msgrcv(qid,(

struct

msgbuf

*

)qbuf,MAX_SEND_SIZE,type,

0

);

d18c02628675d0a2c816449d98bda930.png    printf(

"

Type: %1d Text: %s\n

"

,qbuf

->

mtype,qbuf

->

mtext);

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

void

remove_queue(

int

qid)

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    msgctl(qid,IPC_RMID,

0

);

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

void

change_queue_mode(

int

qid,

char

*

mode)

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

struct

msqid_ds myqueue_ds;

d18c02628675d0a2c816449d98bda930.png    msgctl(qid,IPC_STAT,

&

myqueue_ds);

d18c02628675d0a2c816449d98bda930.png    sscanf(mode,

"

%ho

"

,

&

myqueue_ds.msg_perm.mode);

d18c02628675d0a2c816449d98bda930.png    msgctl(qid,IPC_SET,

&

myqueue_ds);

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

void

usage(

void

)

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    fprintf(stderr,

"

msgtool -A utility for tinkering with msg queue\n

"

);

d18c02628675d0a2c816449d98bda930.png    fprintf(stderr,

"

\nUSAGE:msgtool (s)end  \n

"

);

d18c02628675d0a2c816449d98bda930.png    fprintf(stderr,

"

(r)ecv\n

"

);

d18c02628675d0a2c816449d98bda930.png    fprintf(stderr,

"

(d)elete\n

"

);

d18c02628675d0a2c816449d98bda930.png    fprintf(stderr,

"

(m)ode\n

"

);

d18c02628675d0a2c816449d98bda930.png    exit(

1

);

8f1ba5b45633e9678d1db480c16cae3f.png}

以上程序编译能通过,只是出现了两个warning

warning:内建函数strcpy不兼容的隐式声明

warning:内建函数strlen不兼容的隐式声明

不知是什么原因?是不是gcc版本问题?

还有在写Makefile后,make时出现一个错误提示:

commands commence before first target

解决方法:去掉target的空格(tab键)

程序来是http://tldp.org/LDP/lpg/node45.html#SECTION00742640000000000000

API解释来自http://www.52wg.org/computer/chengxu/200511/computer_98386.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值