System V IPC
消息队列
共享内存
信号量
POSIX IPC
消息队列
共享内存
信号量
互斥锁
条件变量
读写锁
自旋锁
文件锁
$ cat /dev/mqueue/mymq
1. mq_open 函数
功能: 用来创建和访问一个消息队列
原型: 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 : 与open 函数类似,可以是 O_RDONLY, O_WRONLY, O_RDWR, 也可以按位或上O_CREAT,O_EXCL,O_NONBLOCK 等.
mode: 如果oflag指定了 o_creat, 需要设置 mode.
返回值: 成功返回消息队列文件描述符;失败返回-1
2. mq_close 函数
功能:关闭消息队列
原型: mqd_t mq_close(mqd_t mqdes);
参数:
mqdes : 消息队列描述符
返回值:
成功返回0,失败返回-1
3.mq_unlink函数
功能:删除消息队列
原型: mqd_t mq_unlink(const char* name);
参数:
name: 消息队列的名字
返回值: 成功返回0,失败返回-1
4. mq_getattr / mq_setattr
功能:获取/设置消息队列属性
原型:
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,
struct mq_attr *oldattr);
返回值: 成功返回0, 失败返回-1
struct mq_attr {
long mq_flags; /* Flags: 0 or O_NONBLOCK */
long mq_maxmsg; /* Max. # of messages on queue */
long mq_msgsize; /* Max. message size (bytes) */
long mq_curmsgs; /* # of messages currently in queue */
};
5. mq_send
功能: 发送消息
原型:int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
size_t msg_len, unsigned msg_prio,
const struct timespec *abs_timeout);
参数:
mqdes: 消息队列描述符.
msg_ptr: 指向消息的指针
msg_len: 消息长度
msg_prio: 消息优先级
返回值: 成功返回0,失败返回-1
6. mq_receive 函数
功能:接收消息
原型:
ssize_t mq_receive(mqd_t mqdes,char* msg_ptr,size_t msg_len,unsigned * msg_prio);
参数:
mqdes:消息队列描述符
msg_ptr:返回可接收到的消息
msg_len: 消息长度
msg_prio: 返回接收到的消息的优先级
返回值: 成功返回接收的消息字节数,失败返回-1
注意:返回指定消息队列中最高优先级的最早消息
7. mq_notify函数
功能: 建立或者删除消息到达通知事件
原型: int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
参数:
mqdes: 消息队列描述符
sevp:
非空表示消息到达消息队列前为空,那么将得到通知:
NULL表示撤销已注册的通知
返回值: 成功返回0;失败返回-1
通知方式:
产生一个信号
mq_send.c
mq_rece.c
mq_notify.c
Makefile:
消息队列
共享内存
信号量
POSIX IPC
消息队列
共享内存
信号量
互斥锁
条件变量
读写锁
自旋锁
文件锁
Posix消息队列 和 System v消息队列的区别
(1) 对posix消息队列的读总是返回最高优先级的最早消息,对system V消息队列的读则可以返回任意指定优先级的消息
(2)当往一个空队列放置一个消息时,Posix消息队列允许产生一个信号或启动一个线程,System V消息队列则不提供类似机制.
man 7 mq_overview # mkdir /dev/mqueue
# mount -t mqueue none /dev/mqueue
# umout -t mqueue none /dev/mqueue$ cat /dev/mqueue/mymq
1. mq_open 函数
功能: 用来创建和访问一个消息队列
原型: 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 : 与open 函数类似,可以是 O_RDONLY, O_WRONLY, O_RDWR, 也可以按位或上O_CREAT,O_EXCL,O_NONBLOCK 等.
mode: 如果oflag指定了 o_creat, 需要设置 mode.
返回值: 成功返回消息队列文件描述符;失败返回-1
2. mq_close 函数
功能:关闭消息队列
原型: mqd_t mq_close(mqd_t mqdes);
参数:
mqdes : 消息队列描述符
返回值:
成功返回0,失败返回-1
3.mq_unlink函数
功能:删除消息队列
原型: mqd_t mq_unlink(const char* name);
参数:
name: 消息队列的名字
返回值: 成功返回0,失败返回-1
4. mq_getattr / mq_setattr
功能:获取/设置消息队列属性
原型:
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,
struct mq_attr *oldattr);
返回值: 成功返回0, 失败返回-1
struct mq_attr {
long mq_flags; /* Flags: 0 or O_NONBLOCK */
long mq_maxmsg; /* Max. # of messages on queue */
long mq_msgsize; /* Max. message size (bytes) */
long mq_curmsgs; /* # of messages currently in queue */
};
5. mq_send
功能: 发送消息
原型:int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
size_t msg_len, unsigned msg_prio,
const struct timespec *abs_timeout);
参数:
mqdes: 消息队列描述符.
msg_ptr: 指向消息的指针
msg_len: 消息长度
msg_prio: 消息优先级
返回值: 成功返回0,失败返回-1
6. mq_receive 函数
功能:接收消息
原型:
ssize_t mq_receive(mqd_t mqdes,char* msg_ptr,size_t msg_len,unsigned * msg_prio);
参数:
mqdes:消息队列描述符
msg_ptr:返回可接收到的消息
msg_len: 消息长度
msg_prio: 返回接收到的消息的优先级
返回值: 成功返回接收的消息字节数,失败返回-1
注意:返回指定消息队列中最高优先级的最早消息
7. mq_notify函数
功能: 建立或者删除消息到达通知事件
原型: int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
参数:
mqdes: 消息队列描述符
sevp:
非空表示消息到达消息队列前为空,那么将得到通知:
NULL表示撤销已注册的通知
返回值: 成功返回0;失败返回-1
通知方式:
产生一个信号
创建一个线程执行一个指定的函数
$: man 7 sigevent
mq_open.c
#include <unistd.h>
#include <sys/types.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
mqd_t mqid;
mqid = mq_open("/abc",O_CREAT | O_RDWR,0666,NULL);
if(mqid == (mqd_t)-1)
ERR_EXIT("mq_open");
printf("mq_open succ \n");
mq_close(mqid);
return 0;
}
mq_unlink.c
#include <unistd.h>
#include <sys/types.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
mq_unlink("/abc");
return 0;
}
mq_getattr.c
#include <unistd.h>
#include <sys/types.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
mqd_t mqid;
mqid = mq_open("/abc",O_RDONLY);
if(mqid == (mqd_t)-1)
ERR_EXIT("mq_open err");
printf("mq_open succ \n");
struct mq_attr attr;
mq_getattr(mqid,&attr);
printf("max #msg=%ld max #bytes/msg=$%ld #currently on queue=%ld\n",attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);
mq_close(mqid);
return 0;
}
mq_send.c
#include <unistd.h>
#include <sys/types.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
typedef struct stu
{
char name[32];
int age;
}STU;
int main(int argc,char* argv[])
{
if(argc != 2)
{
fprintf(stderr,"Usage:%s<prio>\n",argv[0]);
exit(EXIT_FAILURE);
}
mqd_t mqid;
mqid = mq_open("/abc",O_WRONLY);
if(mqid == (mqd_t)-1)
ERR_EXIT("mq_open");
STU stu;
strcpy(stu.name,"test");
stu.age = 20;
unsigned prio = atoi(argv[1]);
mq_send(mqid,(const char*)&stu,sizeof(stu),prio);
mq_close(mqid);
return 0;
}
mq_rece.c
#include <unistd.h>
#include <sys/types.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
typedef struct stu
{
char name[32];
int age;
}STU;
int main()
{
mqd_t mqid;
mqid = mq_open("/abc",O_RDONLY);
if(mqid == (mqd_t)-1)
ERR_EXIT("mq_open err");
STU stu;
struct mq_attr attr;
mq_getattr(mqid,&attr);
size_t size = attr.mq_msgsize;
unsigned prio;
if(mq_receive(mqid,(char*)&stu,size,&prio) == (mqd_t)-1)
ERR_EXIT("mq_receive");
printf("name=%s age=%d prio=%u\n",stu.name,stu.age,prio);
mq_close(mqid);
return 0;
}
mq_notify.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<mqueue.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<string.h>
#include<signal.h>
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
typedef struct stu
{
char name[32];
int age;
} STU;
size_t size;
mqd_t mqid;
struct sigevent sigev;
void handle(int sig)
{
mq_notify(mqid, &sigev);
STU stu;
unsigned int prio;
mq_receive(mqid, (char *)&stu, size, &prio);
printf("name=%s, age=%d, prio=%d\n", stu.name, stu.age, prio);
}
int main(int argc, char *argv[])
{
mqid = mq_open("/abc", O_RDONLY);
if (mqid == (mqd_t) - 1)
ERR_EXIT("mq_open");
printf("mq_open succ\n");
struct mq_attr attr;
mq_getattr(mqid, &attr);
size = attr.mq_msgsize;
signal(SIGUSR1, handle);
sigev.sigev_notify = SIGEV_SIGNAL;
sigev.sigev_signo = SIGUSR1;
mq_notify(mqid, &sigev);
for (; ;)
pause();
mq_close(mqid);
return 0;
}
Makefile:
.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=mq_open mq_unlink mq_getattr mq_send mq_rece mq_notify
all:$(BIN)
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
mq_open:mq_open.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
mq_unlink:mq_unlink.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
mq_getattr:mq_getattr.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
mq_send:mq_send.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
mq_rece:mq_rece.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
mq_notify:mq_notify.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
clean:
rm -f *.o $(BIN)