【IPC通訊】Posix消息隊列讀寫

先給出建立消息隊列的程序:shell

#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;

    struct mq_attr mqattr;
    mqattr.mq_maxmsg = 3;
    mqattr.mq_msgsize = 1024;
    posixmq = mq_open(MQ_NAME, MQ_FLAG, FILE_MODE, &mqattr); // 建立只可存放三條消息的消息隊列
	if(-1 == posixmq)
	{
		perror("建立MQ失敗");
		exit(1);
	}

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

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

	return 0;
}

編譯並執行:

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

最後程序並無刪除消息隊列(消息隊列有隨內核持續性),如再次執行該程序則會給出錯誤信息:

[infor@s123 PosixMq]$ ./createmq 
建立MQ失敗: File exists

消息隊列的讀寫主要使用下面兩個函數:

#include <mqueue.h>

/*
返回:若成功則爲0, 若出錯則爲-1
*/
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
/*
返回:若成功則爲消息中字節數,若出錯則爲-1
*/
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);

下面給出向消息隊列寫消息的程序:

#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>

/*向消息隊列發送消息,消息隊列名及發送的信息經過參數傳遞*/

int main(int argc, char *argv[])
{
    mqd_t mqd;
    char *ptr;
    size_t len;
    unsigned int prio;
    int rc;

    if(argc != 4)
    {
        printf("Usage: sendmq <name> <bytes> <priority>\n");
        exit(1);
    }

    len = atoi(argv[2]);
    prio = atoi(argv[3]);

    //只寫模式找開消息隊列
    mqd = mq_open(argv[1], O_WRONLY);
    if(-1 == mqd)
    {
        perror("打開消息隊列失敗");
        exit(1);
    }

    // 動態申請一塊內存
    ptr = (char *) calloc(len, sizeof(char));
    if(NULL == ptr)
    {
        perror("申請內存失敗");
        mq_close(mqd);
        exit(1);
    }

    /*向消息隊列寫入消息,如消息隊列滿則阻塞,直到消息隊列有空閒時再寫入*/
    rc = mq_send(mqd, ptr, len, prio);
    if(rc < 0)
    {
        perror("寫入消息隊列失敗");
        mq_close(mqd);
        exit(1);
    }

    // 釋放內存
    free(ptr);

    return 0;
}

編譯並執行:

[infor@s123 PosixMq]$ gcc -o sendmq sendmq.c -lrt
[infor@s123 PosixMq]$ ./sendmq /tmp 30 15
[infor@s123 PosixMq]$ ./sendmq /tmp 30 16
[infor@s123 PosixMq]$ ./sendmq /tmp 30 17
[infor@s123 PosixMq]$ ./sendmq /tmp 30 18

上面前後向消息隊列「/tmp」寫入了四條消息,由於先前建立的消息隊列只容許存放3條消息,本次第四次寫入時程序會阻塞。直到有另外進程從消息隊列取走消息後本次寫入才成功返回。函數

下面經過程序讀消息隊列:spa

#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>

/*讀取某消息隊列,消息隊列名經過參數傳遞*/
int main(int argc, char *argv[])
{
    mqd_t mqd;
    struct mq_attr attr;
    char *ptr;
    unsigned int prio;
    size_t n;
    int rc;

    if(argc != 2)
    {
        printf("Usage: readmq <name>\n");
        exit(1);
    }

    /*只讀模式打開消息隊列*/
    mqd = mq_open(argv[1], O_RDONLY);
    if(mqd < 0)
    {
        perror("打開消息隊列失敗");
        exit(1);
    }

    // 取得消息隊列屬性,根據mq_msgsize動態申請內存
    rc = mq_getattr(mqd, &attr);
    if(rc < 0)
    {
        perror("取得消息隊列屬性失敗");
        exit(1);
    }

    /*動態申請保證能存放單條消息的內存*/
    ptr = calloc(attr.mq_msgsize, sizeof(char));
    if(NULL == ptr)
    {
        printf("動態申請內存失敗\n");
        mq_close(mqd);
        exit(1);
    }

    /*接收一條消息*/
    n = mq_receive(mqd, ptr, attr.mq_msgsize, &prio);
    if(n < 0)
    {
        perror("讀取失敗");
        mq_close(mqd);
        free(ptr);
        exit(1);
    }

    printf("讀取 %ld 字節\n  優先級爲 %u\n", (long)n, prio);

    return 0;
}

編譯並執行:

[infor@s123 PosixMq]$ ./readmq /tmp
讀取 30 字節
  優先級爲 17
[infor@s123 PosixMq]$ ./readmq /tmp
讀取 30 字節
  優先級爲 18
[infor@s123 PosixMq]$ ./readmq /tmp
讀取 30 字節
  優先級爲 16
[infor@s123 PosixMq]$ ./readmq /tmp
讀取 30 字節
  優先級爲 15
[infor@s123 PosixMq]$ ./readmq /tmp

程序執行五次,第一次執行完,先前阻塞在寫處的程序成功返回。第五次執行,由於消息隊列已經爲空,程序阻塞。直到另外的進程向消息隊列寫入一條消息。

 另外,還能夠看出Posix消息隊列每次讀出的都是消息隊列中優先級最高的消息。code


2011-11-17  任洪彩 qdurenhongcai@163.com隊列

轉載請註明出處。進程

相關文章
相關標籤/搜索