1. 程式人生 > >linux中訊息佇列

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資源已存在,或者返回-1。

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環

javaJMS訊息佇列初始

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是相反的, 因為