进程间通信(IPC):消息队列(Message Queue)

消息队列与命名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在。

消息队列函数的定义如下所示:

#include

int msgctl(int msqid, int cmd, struct msqid_ds *buf);//消息队列的控制函数
int msgget(key_t key, int msgflg);//创建很访问一个消息队列
int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);//从一个消息队列中获取消息
int msgsnd(int msqid, const void *msg_ptr,size_tmsg_sz,int msgflg);//把消息添加到消息队列中

msg1.c用于接收消息,msg2.c用于发送消息


msg1.c

/* Here's the receiver program. */

#include 
#include 
#include 
#include 
#include 

#include 


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;

/* First, we set up the message queue. */

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

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

/* Then the messages are retrieved from the queue, until an end message is encountered.
 Lastly, the message queue is deleted. */

    while(running) {
        if (msgrcv(msgid, (void *)&some_data, BUFSIZ,
                   msg_to_receive, 0) == -1) {
            fprintf(stderr, "msgrcv failed with error: %d\n", errno);
            exit(EXIT_FAILURE);
        }
        printf("You wrote: %s", some_data.some_text);
        if (strncmp(some_data.some_text, "end", 3) == 0) {
            running = 0;
        }
    }
    }

    if (msgctl(msgid, IPC_RMID, 0) == -1) {
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
~   


msg2.c

/* The sender program is very similar to msg1.c. In the main set up, delete the
 msg_to_receive declaration and replace it with buffer[BUFSIZ], remove the message
 queue delete and make the following changes to the running loop.
 We now have a call to msgsnd to send the entered text to the queue. */

#include 
#include 
#include 
#include 
#include 

#include 

#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 (msgid == -1) {
        fprintf(stderr, "msgget failed with error: %d\n", errno);
        exit(EXIT_FAILURE);
    }

    while(running) {
        printf("Enter some text: ");
        fgets(buffer, BUFSIZ, stdin);
        some_data.my_msg_type = 1;
        strcpy(some_data.some_text, buffer);

        if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) {
            fprintf(stderr, "msgsnd failed\n");
            exit(EXIT_FAILURE);
        }
        if (strncmp(buffer, "end", 3) == 0) {
            running = 0;
        }
                }

    exit(EXIT_SUCCESS);
}
./msg2
Enter some text: hi
Enter some text: jiajia
Enter some text: end

./msg1
You wrote: hi
You wrote: jiajia
You wrote: end



你可能感兴趣的:(Linux,Programming)