linux进程通信-消息
来源:互联网 发布:xp系统连网络打印机 编辑:程序博客网 时间:2024/05/16 06:57
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msgget(key_t key, int msgflg);
int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);
int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);
- /*msgserver.c*/
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/stat.h>
- #define MSG_FILE "msgserver.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
- /* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */
- /* ipcrm -q <msqid> */
- struct msgtype
- {
- long mtype;
- char buffer[BUFFER+1];
- };
- int main()
- {
- struct msgtype msg;
- key_t key;
- int msgid;
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
- exit(1);
- }
- if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1)
- {
- fprintf(stderr, "Creat Message Error:%s\n", strerror(errno));
- exit(1);
- }
- printf("msqid = %d\n", msgid);
- while(1)
- {
- msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);
- fprintf(stderr,"Server Receive:%s\n", msg.buffer);
- msg.mtype = 2;
- msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
- }
- exit(0);
- }
- /* msgclient.c */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/stat.h>
- #define MSG_FILE "msgserver.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
- struct msgtype {
- long mtype;
- char buffer[BUFFER+1];
- };
- int main(int argc,char **argv)
- {
- struct msgtype msg;
- key_t key;
- int msgid;
- if(argc != 2)
- {
- fprintf(stderr,"Usage:%s string\n", argv[0]);
- exit(1);
- }
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
- exit(1);
- }
- if((msgid=msgget(key, PERM))==-1)
- {
- fprintf(stderr,"Creat Message Error:%s\n", strerror(errno));
- exit(1);
- }
- msg.mtype = 1;
- strncpy(msg.buffer, argv[1], BUFFER);
- msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
- memset(&msg, '\0',sizeof(struct msgtype));
- msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0);
- fprintf(stderr, "Client receive:%s\n", msg.buffer);
- exit(0);
- }
posix消息:
消息队列可以当做一个消息链表,不同于FIFO和管道,某个进程往一个消息队列写入消息之前,不需要另外进程在该队列上等待消息的到达。
对posix消息队列的读总是返回最高优先级的最早消息。
常用函数:
创建或者打开一个消息队列:
#include <fcntl.h> /* For O_* constants */#include <sys/stat.h> /* For mode constants */
#include <mqueue.h>
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);
关闭消息队列:
#include <mqueue.h>
int mq_close(mqd_t mqdes);
删除消息队列:
posix消息队列具备随内核的持续性,就是说即使当前没有进程打开某个消息队列,该队列上的消息也将一直存在。
#include <mqueue.h>int mq_unlink(const char *name);
要真正的删除一个消息队列得这样:调用mq_unlink并让它的引用计数(close一次减少1)达到0。
获取消息队列属性:
#include <mqueue.h>
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,
struct mq_attr *oldattr);
1
//mqcreate.c
01
#include <stdio.h>
02
#include <stdlib.h>
03
#include <unistd.h>
04
#include <mqueue.h>
05
#include <fcntl.h>
06
#include <sys/stat.h>
07
#define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP)
08
struct
mq_attr attr;
//消息队列属性结构体
09
10
int
main(
int
argc,
char
**argv)
11
{
12
int
c, flags;
13
mqd_t mqd;
14
15
flags = O_RDWR | O_CREAT;
16
while
((c = getopt(argc, argv,
"em:z:"
)) != -1) {
//处理参数,带冒号的表示后面有参数的
17
switch
(c) {
18
case
'e'
:
19
flags |= O_EXCL;
20
printf
(
"the optind is :%d\n"
,optind);
21
break
;
22
case
'm'
:
23
attr.mq_maxmsg =
atol
(optarg);
24
printf
(
"the optind is :%d\n"
,optind);
25
break
;
26
case
'z'
:
27
attr.mq_msgsize =
atol
(optarg);
28
printf
(
"the optind is :%d\n"
,optind);
29
break
;
30
}
31
}
32
if
(optind != argc - 1) {
33
printf
(
"usage: mqcreate [-e] [-m maxmsg -z msgsize] <name>"
);
34
exit
(0);
35
}
36
37
if
((attr.mq_maxmsg != 0 && attr.mq_msgsize == 0) || (attr.mq_maxmsg == 0 && attr.mq_msgsize !=0)){
38
printf
(
"must specify both -m maxmsg and -z msgsize"
);
39
exit
(0);
40
}
41
42
mqd = mq_open(argv[optind], flags, FILEMODE, (attr.mq_maxmsg != 0) ? &attr : NULL);
43
mq_close(mqd);
44
exit
(0);
45
}
1
//mqsend.c
01
#include <stdio.h>
02
#include <stdlib.h>
03
#include <unistd.h>
04
#include <mqueue.h>
05
06
07
int
main(
int
argc,
char
**argv)
08
{
09
mqd_t mqd;
10
void
*ptr;
11
size_t
len;
12
unsigned
int
prio;
13
14
if
(argc != 4) {
15
printf
(
"usage: mqsend <name> <#bytes> <priority>"
);
16
exit
(0);
17
}
18
len =
atoi
(argv[2]);
19
prio =
atoi
(argv[3]);
20
21
if
((mqd = mq_open(argv[1], O_WRONLY)) == -1){
22
printf
(
"open error"
);
23
exit
(0);
24
}
25
ptr =
calloc
(len,
sizeof
(
char
));
26
mq_send(mqd, ptr, len, prio);
27
exit
(0);
28
}
1
//mqrecieve.c
01
#include <stdio.h>
02
#include <stdlib.h>
03
#include <unistd.h>
04
#include <mqueue.h>
05
06
int
main(
int
argc,
char
**argv)
07
{
08
int
c, flags;
09
mqd_t mqd;
10
ssize_t n;
11
unsigned
int
prio;
12
void
*buff;
13
struct
mq_attr attr;
14
flags = O_RDONLY;
15
while
((c = getopt(argc, argv,
"n"
)) != -1){
16
switch
(c) {
17
case
'n'
:
18
flags |= O_NONBLOCK;
19
break
;
20
}
21
}
22
if
(optind != argc-1) {
23
printf
(
"usage: mqreceive [-n] <name>"
);
24
exit
(0);
25
}
26
27
mqd = mq_open(argv[optind], flags);
28
mq_getattr(mqd, &attr);
29
30
buff =
malloc
(attr.mq_msgsize);
31
32
n = mq_receive(mqd, buff, attr.mq_msgsize, &prio);
33
printf
(
"read %ld bytes, priority = %u\n"
,(
long
) n,prio);
34
exit
(0);
35
}
- linux进程通信-消息
- linux消息队列进程通信
- linux消息队列进程通信
- linux消息队列进程通信
- linux进程通信---消息队列
- linux进程通信--消息队列
- linux进程通信--消息队列
- 【Linux】 进程通信--消息队列
- linux进程通信---消息队列
- linux进程通信-消息队列
- Linux进程间通信: 消息队列
- Linux进程间通信: 消息队列
- linux进程间通信之消息队列
- linux C-(进程间通信 消息队列)
- linux进程间通信之消息队列
- Linux高级进程间通信:消息队列
- linux 进程间通信之消息传递
- linux 进程间通信之消息传递
- 关于php时区时间错误问题
- Linux进程通信-信号量
- Java中的Class類
- Linux(CentOS 5.5) Redis 安装及RedisPHP拓展安装应用
- 第一章 代码无错就是优?简单工厂模式(读书笔记)
- linux进程通信-消息
- 几个AR翻译APP
- 获取cookies
- Fortran 2003的新特性 –终结例程 Final subroutines
- 12-1-31进步一小点
- 常见bootloader介绍
- linux进程通信-共享内存
- js设置两个table中的td的宽度
- 小布老师所有视频