【IPC通訊】Posix消息隊列的建立

消息隊列能夠認爲是一個消息鏈表。進程(線程)能夠往裏寫消息,也能夠從裏面取出消息。shell

前面講到的管道和FIFO在寫入消息時必須有進程讀,不然是一直阻塞的。而消息隊列則不一樣,一個進程能夠往某個消息隊列裏寫消息,而後終止,另外一個進程隨時能夠從消息隊列裏取走這些消息。這裏也說明了,消息隊列具備隨內核的持續性,也就是系統不重啓,消息隊列永久存在。編程

#include <mqueue.h>

/*
函數說明:函數建立或打開一個消息隊列
返回值:成功返回消息隊列描述符,失敗返回-1,錯誤緣由存於errno中
*/
mqd_t mq_open(const char *name, int oflag, .../* mode_t mode, struct mq_attr *attr */);

/*
函數說明:關閉一個打開的消息隊列,表示本進程再也不對該消息隊列讀寫
返回值:成功返回0,失敗返回-1,錯誤緣由存於errno中
*/
int mq_close(mqd_t mqdes);

/*
函數說明:刪除一個消息隊列,比如刪除一個文件,其餘進程再也沒法訪問
返回值:成功返回0,失敗返回-1,錯誤緣由存於errno中
*/
int mq_unlink(const char *name);

下面經過程序看一下如何建立(並打開)、關閉、刪除一個消息隊列。

#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define MQ_NAME ("/tmp")
#define MQ_FLAG (O_RDWR | O_CREAT | O_EXCL) // 建立MQ的flag
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) // 設定建立MQ的權限

int main()
{
    mqd_t posixmq;
	int rc = 0;

    posixmq = mq_open(MQ_NAME, MQ_FLAG, FILE_MODE, NULL);
	if(-1 == posixmq)
	{
		perror("建立MQ失敗");
		exit(1);
	}

	rc = mq_close(posixmq);
	if(0 != rc)
	{
		perror("關閉失敗");
		exit(1);
	}

	rc = mq_unlink(MQ_NAME);
	if(0 != rc)
	{
		perror("刪除失敗");
		exit(1);
	}

	return 0;
}

編譯並執行:網絡

[infor@s123 PosixMq]$ gcc -o createmq createmq.c -lrt

[infor@s123 PosixMq]$ ./createmq

編譯這個程序須要注意幾點:函數

一、由於mq_XXX()函數不是標準庫函數,連接時須要指定;庫-lrt
二、消息隊列的名字最好使用「/」打頭,而且只有一個「/」的名字。不然可能出現移植性問題;(還需保證在根目錄有寫權限)
三、建立成功的消息隊列不必定能看到,(使用一些方法也能夠看到,本文不作介紹);spa

至於爲何消息隊列的名字有如此規定,引用《UNIX網絡編程 卷2》的相關描述:
mq_open,sem_open,shm_open這三個函數的第一個參數是一個IPC名字,它多是某個文件系統中的一個真正存在的路徑名,也可能不是。Posix.1是這樣描述Posix IPC名字的。
一、它必須符合已有的路徑名規則(最多由PATH_MAX個字節構成,包括結尾的空字節)
二、若是它以斜槓開頭,那麼對這些函數的不一樣調用將訪問同一個隊列,不然效果取決於實現(也就是效果沒有標準化)
三、名字中的額外的斜槓符的解釋由實現定義(一樣是沒有標準化)
所以,爲便於移植起見,Posix IPC名字必須以一個斜槓打頭,而且不能再包含任何其餘斜槓符。

2011-11-14 任洪彩 qdurenhongcai@163.com
轉載請註明出處。
相關文章
相關標籤/搜索