现在的位置: 首页 > 综合 > 正文

Linux IPC机制:消息队列示例

2018年03月18日 ⁄ 综合 ⁄ 共 2011字 ⁄ 字号 评论关闭

程序msg1.c用于接收消息

<span style="font-size:12px;">#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <sys/msg.h>

struct my_msg_st {
    long int my_msg_type;
    char some_text[BUFSIZ];
};

int main()
{
    int running = 1;
    int msgid;
    struct my_msg_st some_data;
    long int msg_to_receive = 0;

    //建立消息队列
    msgid = msgget( (key_t)1234, 0666 | IPC_CREAT );

    if( -1 == msgid ) {
        fprintf( stderr, "msgget failed with error:%d\n", errno );
        exit( EXIT_FAILURE );
    }

    //从消息队列中获取消息 直到遇见end为止
    while( running ) {
        memset( some_data.some_text, '\0', BUFSIZ );
        if( -1 == msgrcv( msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0 ) ) {
            fprintf( stderr, "magrcv failed with error %d\n", errno );
            exit( EXIT_FAILURE );
        }

        printf("You wrote: %s", some_data.some_text );
        some_data.some_text[strlen(some_data.some_text)-1] = '\0'; //去掉换行符 以准确找到 结束标志字符串 end
        if( 0 == strcmp( some_data.some_text, "end" ) )
            running = 0;
    }

    //删除消息队列
    if( -1 == msgctl( msgid, IPC_RMID, 0 ) ) {
            fprintf( stderr, "msgctl(IPC_RMID) failed\n");
            exit( EXIT_FAILURE );
    }

    exit( EXIT_SUCCESS );
}</span>


程序 msg2.c 用于发送消息:

<span style="font-size:12px;">#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <sys/msg.h>
#define MAX_TEXT 512

struct my_msg_st {
    long int my_msg_type;
    char some_text[MAX_TEXT];
};

int main()
{
    int running = 1;
    struct my_msg_st some_data;
    int msgid;
    char buffer[BUFSIZ];

    msgid = msgget( (key_t)1234, 0666 | IPC_CREAT );

    if( -1 == msgid ) {
        fprintf( stderr, "msgget failed with error %d\n", errno );
        exit( EXIT_FAILURE );
    }

    //发送消息
    while( running ) {
        memset( buffer, '\0', BUFSIZ );
        printf("Enter some text: ");
        fgets( buffer, BUFSIZ, stdin );
        some_data.my_msg_type = 1;
        strcpy( some_data.some_text, buffer );

        if( -1 == msgsnd( msgid, (void *)&some_data, MAX_TEXT, 0 ) ) {
            fprintf( stderr, "msgsnd failed with error %d\n", errno );
            exit( EXIT_FAILURE );
        }
        buffer[strlen(buffer)-1] = '\0';
        if( 0 == strcmp( buffer, "end" ) )
            running = 0;
    }
    exit( EXIT_SUCCESS);
}</span>

输出结果:

[zhang@localhost document]$ ./msg2
Enter some text: hey man
Enter some text: how are you
Enter some text: endsss
Enter some text: end
[zhang@localhost document]$ ./msg1
You wrote: hey man
You wrote: how are you
You wrote: endsss
You wrote: end

与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在,这消除了同步命名管道的打开和关闭时可能产生的一些困难。

抱歉!评论已关闭.