System V 訊息佇列(一)
一、訊息佇列
1、訊息佇列提供了一個從一個程式向另外一個程式傳送一塊資料的方法
2、每個資料塊都被認為是有一個型別,接收者程式接收的資料塊可以有不同的型別值
3、訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先入先出。
4、訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(MSGMAX),每個訊息佇列的總的位元組數是有上限的(MSGMNB),系統上訊息佇列的總數也有一個上限(MSGMNI),這三個引數都可以檢視:
cjl@S405:~$ cat /proc/sys/kernel/msgmax #一條訊息的長度
8192
cjl@S405:~$ cat /proc/sys/kernel/msgmnb # 一個訊息佇列總的容納長度
16384
cjl@S405:~$ cat /proc/sys/kernel/msgmni #系統中建立訊息佇列的最大個數
1663
二. IPC物件資料結構
核心為每個IPC物件維護一個資料結構,在<sys/msg.h>標頭檔案中,該標頭檔案在ubuntu系統下的路徑:/usr/include/linux
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
四.訊息佇列在核心中的表示
五.訊息佇列函式
返回值:
成功返回非負整數,即訊息佇列的標識碼
失敗:返回-1
#ipcrm -q msgid # 刪除命令
#ipcrm -Q key # 刪除命令,如何key為0,則不能刪除
------------------------------------------------------------------------------------
刪除訊息佇列:msg_rmid.c
設定訊息佇列的許可權:msg_set.c
列印訊息佇列的狀態資訊:msg_stat.c
makefile檔案:
1、訊息佇列提供了一個從一個程式向另外一個程式傳送一塊資料的方法
2、每個資料塊都被認為是有一個型別,接收者程式接收的資料塊可以有不同的型別值
3、訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先入先出。
4、訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(MSGMAX),每個訊息佇列的總的位元組數是有上限的(MSGMNB),系統上訊息佇列的總數也有一個上限(MSGMNI),這三個引數都可以檢視:
cjl@S405:~$ cat /proc/sys/kernel/msgmax #一條訊息的長度
8192
cjl@S405:~$ cat /proc/sys/kernel/msgmnb # 一個訊息佇列總的容納長度
16384
cjl@S405:~$ cat /proc/sys/kernel/msgmni #系統中建立訊息佇列的最大個數
1663
二. IPC物件資料結構
核心為每個IPC物件維護一個資料結構,在<sys/msg.h>標頭檔案中,該標頭檔案在ubuntu系統下的路徑:/usr/include/linux
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
四.訊息佇列在核心中的表示
訊息佇列是用連結串列實現的,這裡需要提出的是MSGMAX指的是一條訊息的純資料大小的上限,下圖是一個 訊息佇列,則其純資料總和不能超過MSGMNB,像這樣一條訊息佇列,系統含有的總數不能超過MSGMNI 個。
五.訊息佇列函式
(1) 功能:用來建立和訪問一個訊息佇列
int msgget(key_t key, // 某個休息佇列的名字
int msgflg); //由個許可權標誌組成,它們的用法和建立檔案時使用的mode模式標誌時一樣的返回值:
成功返回非負整數,即訊息佇列的標識碼
失敗:返回-1
(2)功能:訊息佇列的控制函式
int msgctl(int msgid, //msgget函式返回的訊息佇列識別符號
int cmd, // 採取的動作struct msgid_ds *buf); //
返回值: 成功返回0失敗返回-1
cmd 的取值如下:
會用到的命令
-----------------------------------------------------------------------------------
# ipcs -q #檢視IPC訊息佇列命令#ipcrm -q msgid # 刪除命令
#ipcrm -Q key # 刪除命令,如何key為0,則不能刪除
------------------------------------------------------------------------------------
建立一個訊息佇列: msg_get.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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)
int main()
{
int msgid;
//msgid = msgget(1234,0666 | IPC_CREAT);
msgid = msgget(1234,0666 | IPC_CREAT | IPC_EXCL);
//msgid = msgget(IPC_PRIVATE,0666 | IPC_CREAT | IPC_ECEC);// 建立的不能夠共享的
//msgid = msgget(IPC_PRIVATE,0666);
msgid = msgget(1234,0); // 如果訊息佇列已經存在,則開啟訊息佇列
if(msgid == -1)
ERR_EXIT("msgget err");
printf("msgget success \n");
printf("msgid=%d\n",msgid);
return 0;
}
刪除訊息佇列:msg_rmid.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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)
int main()
{
int msgid;
msgid = msgget(1234,0); // 如果訊息佇列已經存在,則開啟訊息佇列
if(msgid == -1)
ERR_EXIT("msgget err");
printf("msgget success \n");
printf("msgid=%d\n",msgid);
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
設定訊息佇列的許可權:msg_set.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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)
int main()
{
int msgid;
msgid = msgget(1234,0); // 如果訊息佇列已經存在,則開啟訊息佇列
if(msgid == -1)
ERR_EXIT("msgget err");
printf("msgget success \n");
printf("msgid=%d\n",msgid);
struct msqid_ds buf;
msgctl(msgid,IPC_STAT,&buf); // 必須得先獲取
sscanf("600","%o",(unsigned int *)&buf.msg_perm.mode); // 以八進位制輸入到buf
msgctl(msgid,IPC_SET,&buf); // 再設定
return 0;
}
列印訊息佇列的狀態資訊:msg_stat.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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)
int main()
{
int msgid;
msgid = msgget(1234,0); // 如果訊息佇列已經存在,則開啟訊息佇列
if(msgid == -1)
ERR_EXIT("msgget err");
printf("msgget success \n");
printf("msgid=%d\n",msgid);
struct msqid_ds buf;
msgctl(msgid,IPC_STAT,&buf);
printf("mode=%o\n",buf.msg_perm.mode);
printf("bytes=%ld\n",buf.__msg_cbytes);
printf("number=%d\n",(int)buf.msg_qnum);
printf("msgmnb=%d\n",(int)buf.msg_qbytes);
return 0;
}
makefile檔案:
.PHONY:clean all
cc=gcc
CFLAGS=-Wall -g
BIN=msg_get msg_rmid msg_stat msg_set
all:$(BIN)
%.o:%.c
$(cc) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o $(BIN)
相關文章
- linux 程式間通訊之System V 訊息佇列Linux佇列
- 訊息佇列系列一:訊息佇列應用佇列
- linux程式間通訊-----System V訊息佇列總結例項Linux佇列
- 訊息佇列(一)佇列
- Sytem V訊息佇列(二)佇列
- 訊息佇列佇列
- linux 程式間通訊之System V 訊息佇列 www.weiboke.onlineLinux佇列
- 訊息佇列(MQ)佇列MQ
- Kafka訊息佇列Kafka佇列
- RabbitMQ訊息佇列MQ佇列
- kafka 訊息佇列Kafka佇列
- POSIX訊息佇列佇列
- 訊息佇列(二)佇列
- 訊息佇列二佇列
- [Redis]訊息佇列Redis佇列
- [訊息佇列]rocketMQ佇列MQ
- [訊息佇列]RabbitMQ佇列MQ
- 訊息佇列全面瞭解(一)佇列
- RabbitMQ 訊息佇列之佇列模型MQ佇列模型
- 全面理解Handler-1:理解訊息佇列,手寫訊息佇列佇列
- 如何設計一個訊息佇列?佇列
- MQ訊息佇列_RabbitMQMQ佇列
- Java面試—訊息佇列Java面試佇列
- 訊息佇列雜談佇列
- 訊息佇列二三事佇列
- rabbitmq訊息佇列原理MQ佇列
- 訊息佇列設計佇列
- 訊息佇列簡史佇列
- 訊息佇列之RabbitMQ佇列MQ
- 訊息佇列之RocketMQ佇列MQ
- 理解訊息佇列(MQ)佇列MQ
- 訊息佇列之 RabbitMQ佇列MQ
- 訊息佇列之 Kafka佇列Kafka
- 訊息佇列之 ActiveMQ佇列MQ
- 訊息佇列深入解析佇列
- 訊息佇列之 RocketMQ佇列MQ
- 分散式訊息佇列分散式佇列
- RabbitMQ 訊息佇列 配置MQ佇列