linux中訊息佇列
訊息佇列
1.建立新訊息佇列或取得已存在訊息佇列
原型:int msgget(key_t key, int msgflg);引數:
key:可以認為是一個埠號,也可以由函式ftok生成。
msgflg:
IPC_CREAT:如果IPC不存在,則建立一個IPC資源,否則開啟操作。IPC_EXCL:只有在共享記憶體不存在的時候,新的共享記憶體才建立,否則就產生錯誤。
如果單獨使用IPC_CREAT,XXXget()函式要麼返一個已經存在的共享記憶體的操作符,要麼返回一個新建的共享記憶體的識別符號。
如果將IPC_CREAT和IPC_EXCL標誌一起使用,XXXget()將返回一個新建的IPC識別符號
IPC_EXEL標誌本身並沒有太大的意義,但是和IPC_CREAT標誌一起使用可以用來保證所得的物件是新建的,而不是開啟已有的物件。
2.向佇列讀/寫訊息
原型:msgrcv從佇列中取⽤用訊息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, intmsgflg);
msgsnd將資料放到訊息佇列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
引數:
msgid:訊息佇列的標識
msgp:指向訊息緩衝區的指標,此位置用來暫時儲存傳送和接收的訊息,是一個使用者可struct msgstru{
long mtype; //大於0
char mtext[使用者指定大小];};
msgsz:訊息的大小。
msgtyp:從訊息佇列內讀取的訊息形態。如果值為零,則表示訊息佇列中的所有訊息都會被讀取。
msgflg:用來指明核心程式在佇列沒有資料的情況下所應採取的行動。如果msgflg和常數IPC_NOWAIT合用,則在msgsnd()執行時若是訊息佇列已滿,則msgsnd()將不會阻塞,而會立即返回-1,如果執行的是msgrcv(),則在訊息佇列呈空時,不做等待馬上返回-1,並設定錯誤碼為ENOMSG。當msgflg為0時,msgsnd()及msgrcv()在佇列呈滿或呈空的情形時,採取阻塞等待的處理模式。
3.設定訊息佇列屬性
原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );引數:msgctl 系統呼叫對 msgqid 標識的訊息佇列執行 cmd 操作,系統定義了 3 種 cmd 操作IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 該命令用來獲取訊息佇列對應的 msqid_ds 資料結構,並將其儲存到 buf 指定的地址空間。
IPC_SET : 該命令用來設定訊息佇列的屬性,要設定的屬性儲存在buf中。
IPC_RMID : 從核心中刪除 msqid 標識的訊息佇列。
4、程式碼如下
Makefile中的程式碼
client_=client
server_=server
cc=gcc
cliSrc=client.c comm.c
serSrc=server.c comm.c
.PHONY:all
all:$(client_) $(server_)
$(client_):$(cliSrc)
$(cc) -o [email protected] $^
$(server_):$(serSrc)
$(cc) -o [email protected] $^
.PHONY:clean
clean:
rm -f $(client_) $(server_)
1、標頭檔案comm.h中的程式碼
#ifndef _COMM_H_
#define _COMM_H_
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#define PATHNAME "."
#define PROJ_ID 0x6666
#define SIZE 128
#define SERVER_TYPE 1
#define CLIENT_TYPE 2
struct msgbuf{
long mtype;
char mtext[SIZE];
};
int createMsgQueue();
int getMsgQueue();
int sendMsg(int msgid,long type,const char* info);
int recvMsg(int msgid,long type,char out[]);
int destroyMsgQueue(int);
#endif
2、編寫檔案comm.c中的程式碼
#include"comm.h"
int commMsgQueue(int flag)
{
key_t k = ftok(PATHNAME,PROJ_ID);
if(k < 0){
perror("ftok");
return -1;
}
int msg_id = msgget(k,flag);
if(msg_id < 0){
perror("msg_id");
return -2;
}
return msg_id;
}
int createMsgQueue()
{
return commMsgQueue(IPC_CREAT|IPC_EXCL|0666);
}
int getMsgQueue()
{
return commMsgQueue(IPC_CREAT);
}
int sendMsg(int msgid,long type,const char* info)
{
struct msgbuf msg;
msg .mtype = type;
strcpy(msg.mtext,info);
if(msgsnd(msgid,&msg,sizeof(msg.mtext),0) < 0){
perror("msgsnd");
return -1;
}
return 0;
}
int recvMsg(int msgid,long type,char out[] )//recrve
{
struct msgbuf msg;
if(msgrcv(msgid,&msg,sizeof(msg.mtext),type,0) < 0){
perror("recvMsg");
return -1;
}
strcpy(out,msg.mtext);
return 0;
}
int destroyMsgQueue(int msgid)
{
if(msgctl(msgid,IPC_RMID,NULL) < 0){
perror("msgctl");
return -1;
}
return 0;
}
3、伺服器端程式碼
#include"comm.h"
int main()
{
int msgid = createMsgQueue();
printf("msgid: %d\n",msgid);
char buf[SIZE];
while(1){
recvMsg(msgid,CLIENT_TYPE,buf);
printf("client# %s\n",buf);
printf("please Enter$");
fflush(stdout);
ssize_t s = read(0,buf,sizeof(buf)-1);
if(s > 0){
buf[s-1] = '\0';
sendMsg(msgid,SERVER_TYPE,buf);
}
}
destroyMsgQueue(msgid);
return 0;
}
4、客戶端程式碼
#include"comm.h"
int main()
{
int msgid = getMsgQueue();
printf("msgid: %d\n",msgid);
//int i = 0;
char buf[SIZE];
while(1){
printf("please Enter$");
fflush(stdout);
ssize_t s = read(0,buf,sizeof(buf)-1);
if(s > 0){
buf[s-1] = '\0';
sendMsg(msgid,CLIENT_TYPE,buf);
sleep(1);
// i++;
}
recvMsg(msgid,SERVER_TYPE,buf);
printf("server# %s\n",buf);
}
// destroyMsgQueue(msgid);
return 0;
}
執行客戶端提示輸入:
執行伺服器端接收然後提示輸入:
相關推薦
linux中訊息佇列
訊息佇列 1.建立新訊息佇列或取得已存在訊息佇列 原型:int msgget(key_t key, int msgflg);引數:key:可以認為是一個埠號,也可以由函式ftok生成。 msgflg: IPC_CREAT:如果IPC不存在,則建立一個IPC資源,否則開啟
linux中訊息佇列kfifo和訊號量sem_t的用法
使用kfifo和sem_t配合來實現訊息佇列:由sem來管理目前可以傳送和接收的總的訊息數,由kfifo來儲存訊息。具體實現起來就是定義訊號量sem_t_send和sem_t_recv,sem_t_send設為max_num,sem_t_recv設為0。
對Linux中訊息佇列和訊號量集合的理解
訊息佇列和訊號量集合同樣作為程序間通訊的重要手段,是LInux程式設計必需理解的內容,但兩者類似的操作和檔案結構讓很多人不能理解其中的原理。下面我來介紹下我的理解: 在使用訊息佇列和訊號量集合前都必須使用的一個函式Key_t ftok(char *pathname,char
Linux作業系統--訊息佇列
1、訊息佇列的特點 (1)訊息佇列是訊息的連結串列,具有特定的格式,存放在記憶體中並由訊息佇列識別符號標識. (2)訊息佇列允許一個或多個程序向它寫入與讀取訊息. (3)管道和命名管道都是通訊資料都是先進先出的原則。 (4)訊息佇列可以實現訊息的隨機查詢,訊息不一定要
OpenStack中訊息佇列(RabbitMQ)分析
可以說OpenStack使用這種MOM模式的訊息佇列機制無疑是一個聰明的選擇。其鬆耦合性以及動態可擴充套件性都非常符合開源雲的要求。無論是開發還是執行,都會帶了很多好處。唯一的缺點就是它是一個single point failure,如果RabbitMQ出錯了,那整個OpenStack也就無法運行了。雖然R
Python中訊息佇列的使用
#!/usr/bin/evn python # -*- coding:utf-8 -*- import threading import Queue import time # 建立一個訊息佇列 message=Queue.Queue(); # 生產者的
Linux POSIX 訊息佇列
程式執行時,服務程序阻塞於mq_receive,客戶程序每發一條訊息佇列,服務程序都會從mq_receive處返回,但不一定接收到的訊息就是客戶程序最近傳送的那一條訊息,因為客戶程序往訊息佇列中新增訊息時會按照優先順序來排序,如果客戶程序同時向訊息佇列新增多條訊息,服務程序還未來得及讀取,那麼
Linux之訊息佇列機制
一.訊息佇列先知 其實,訊息佇列與命名管道有很多相似之處,但少了在開啟和關閉管道方面的複雜性。但使用訊息佇列應為解決我們在,命名管道時遇到的一些問題,比如管道的阻塞問題。 訊息佇列提供了一種子啊兩個
Linux中程序間通訊機制----訊息佇列
一、什麼是訊息 訊息(message)是一個格式化的可變長的資訊單元。訊息機制允許由一個程序給其它任意的程序傳送一個訊息。當一個程序收到多個訊息時,可將它們排成一個訊息佇列。 1、訊息機制的資料結構 (1)訊息首部 記錄一些與訊息有關的資訊,如訊息的型別、大小、
linux ELK(filebeat)環境搭建中加入kafka訊息佇列的詳細介紹(菜鳥新手級別)
本文所使用的軟體版本如下filebeat 5.4.0,elasticsearch 5.4.0,kibana 5.4.0, 最近公司需要做實時日誌分析系統,在網上查了很多資料,發現ELK是最適合的,而且是開源,官方文件還算詳細。 儘管ELK環
java中JMS訊息佇列初始
1.什麼是訊息佇列: JMS是一個訊息服務的標準或者說是規範,允許應用程式元件基於JavaEE平臺建立、傳送、接收和讀取訊息。它使分散式通訊耦合度更低,訊息服務更加可靠以及非同步性。 2.JMS基本概念: JMS是ja
RocketMQ中介軟體訊息佇列在Maven專案中的配置使用操作 (分散式釋出訂閱訊息系統)
一、專案引用 <dependency> <groupId>com.foriseland.fjf.mq</groupId> <artifactI
Kafka-API中介軟體MQ訊息佇列在Maven專案中的配置使用操作 (分散式釋出訂閱訊息系統)
一、 Maven依賴 <dependency> <groupId>com.foriseland.fjf.mq</groupId> <artifactId>fjf-mq-kafka</artifactId> &
Linux-程序通訊-訊息佇列/訊號燈/共享記憶體
訊息佇列 訊息佇列提供了程序間傳送資料塊的方法,每個資料塊都可以被認為是有一個型別,接受者接受的資料塊可以有不同的型別;我們可以通過傳送訊息來避免命名管道的同步和阻塞問題;訊息佇列與命名管道一樣,每個資料塊都有一個最大長度的限制;我們可以將每個資料塊當作是一
RabbitMQ如何在命令列下清除訊息佇列中的所有資料
最近在研究 RabbitMQ 訊息佇列, 安裝好進行測試的時候發覺在一個名為 MyRabbitMQ 的訊息佇列中已經插入了大量的資料。 最後不得不找方法清除。 首先定位到 rabbitMQ 安裝目錄的sbin 目錄下。 然後shift+右鍵 。 調出右鍵選單。 選擇在此處開啟
C++封裝Linux訊息佇列
訊息佇列是Linux程序間通訊方式之一,在面向物件程式設計中,需要對其封裝。 一、訊息佇列的特點 1、非同步通訊,訊息佇列會儲存程序傳送的訊息,其他程序不一定要及時取走訊息。 2、可以傳送不同型別的訊息,訊息的頭部用long型別的欄位標記。 3、取訊息時,不一定按先進
Linux:程序間通訊(匿名管道命名管道)(共享記憶體,訊息佇列,訊號量)
目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 | 命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲
Linux訊息佇列與執行緒例項理解
相較於程序,執行緒不僅擁有程序的併發性,相互獨立等特點,更有佔用資源較少,效率高等特點。 建立執行緒 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)
Spring Boot中使用WebSocket總結(三):使用訊息佇列實現分散式WebSocket
在上一篇文章(www.zifangsky.cn/1359.html)中我介紹了服務端如何給指定使用者的客戶端傳送訊息,並如何處理對方不線上的情況。在這篇文章中我們繼續思考另外一個重要的問題,那就是:如果我們的專案是分散式環境,登入的使用者被Nginx的反向代理分配到多個不同伺服器,那麼在其中一個伺服器建立了W
linux c程式設計:Posix訊息佇列
Posix訊息佇列可以認為是一個訊息連結串列. 有足夠寫許可權的執行緒可以往佇列中放置訊息, 有足夠讀許可權的執行緒可以從佇列中取走訊息 在某個程序往一個佇列寫入訊息前, 並不需要另外某個程序在該佇列上等待訊息的到達. 這跟管道和FIFO是相反的, 因為