1. 程式人生 > >多程序通訊之訊息佇列

多程序通訊之訊息佇列

下面是原始碼:
#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/msg.h>

#define MAX_DATA_LENGTH  2048

struct Message_Queue  
{  
    int msg_type;  
    char Msg_Data[MAX_DATA_LENGTH];  
};  
int running = 1;  
int msgid = -1;  
long int msgtype = 0;   

char buffer[BUFSIZ+1] = {0};  

int main(void)
{
    pid_t pid;
    struct Message_Queue message;  //要是宣告為 *message,則必須手動分配空間,不然會段錯誤
    //建立訊息佇列  
    msgid = msgget((key_t)1106, 0666 | IPC_CREAT);   //key值可通過ftok函式生成,也可以自己寫一個整數
    if(msgid == -1)  
    {  
        fprintf(stderr, "msgget failed with error: %d\n", errno);  
        exit(EXIT_FAILURE);  
    }  

    if((pid = fork())==-1)
    {
        perror("Fail to fork");
        exit(EXIT_SUCCESS);
    }

    if(pid!=0)  //父程序負責傳送訊息
    {
        //向訊息佇列中寫訊息,直到寫入end  
        while(running)  
        {  
            //輸入資料 
            bzero(buffer,sizeof(buffer));	
            bzero(message.Msg_Data,sizeof(message.Msg_Data)); //清空陣列,不然讀取的時候會發生錯誤			
            printf("Enter some Msg_Data: ");  
            fgets(buffer, BUFSIZ, stdin);  
            message.msg_type = 1;    //注意2  

            strncpy(message.Msg_Data,buffer,strlen(buffer));
            //strncpy時是沒有拷貝'\0'的,所以要加上,不然讀的時候列印會有亂碼
            message.Msg_Data[strlen(message.Msg_Data)-1] = '\0';
            //message.msg_type = 1;    //注意2 
            //向佇列傳送資料  
            if(msgsnd(msgid, (void*)&message, MAX_DATA_LENGTH, 0) == -1)  
            {  
                fprintf(stderr, "msgsnd failed\n");  
                exit(EXIT_FAILURE);  
            }  
            //輸入end結束輸入  
            if(strncmp(buffer, "end", 3) == 0)  
                running = 0;  
            sleep(1);  
        }  
        exit(EXIT_SUCCESS);  
    }

    if(pid==0)   //子程序負責讀訊息
    {
        //從佇列中獲取訊息,直到遇到end訊息為止  
        while(running)  
        {  
            if(msgrcv(msgid, (void*)&message, BUFSIZ, msgtype, 0) == -1)  
            {  
                fprintf(stderr, "msgrcv failed with errno: %d\n", errno);  
                exit(EXIT_FAILURE);  
            }  
            printf("You wrote: %s\n",message.Msg_Data);  
            //遇到end結束  
            if(strncmp(message.Msg_Data, "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);  
    }

    exit(EXIT_SUCCESS);
}