進程間通信(IPC)3 ------ 消息隊列 - 2

      上文將消息隊列中放入了數據,其他進程就可以從中讀取消息了。讀取消息的函數是msgrcv(),該函數原型爲:

#include <sys/msg.h>
int msgrcv(int msgid, struct msgbuf *msgp, size_t msgsz, long int msgtyp, int msgflg);

      相關參數的含義上文已經說明,此處略過。

      使用相同的參數PATH_NAME和PROJ_ID來調用ftok()函數,發現在不同的進程中調用它生成的msgkey並不一致。這導致從消息隊列裏讀取消息失敗。兩次在不同進程中使用相同的參數調用ftok函數,生成的msgkey的情況,參看下圖:




      那麼現在必須修改代碼,在讀取消息的進程中,必須顯示地指明寫入消息時用到的msgkey。否則讀取消息失敗。以下代碼,將msgkey硬編碼進了msgget函數中:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define BUF_SIZE	256
#define PROJ_ID		32
#define PATH_NAME	"."

int main(void)
{
	/*用戶自定義消息緩衝區*/
	struct mymsgbuf{
		long msgtype;
		char ctrlstring[BUF_SIZE];
	} msgbuffer;
	int		qid;     /*消息隊列標識符*/
	int		msglen;
	key_t	msgkey;

	/*獲取鍵值*/
	if((msgkey = ftok(PATH_NAME, PROJ_ID)) == -1)
	{
		perror("ftok error!\n");
		exit(1);
	}else{
		printf("msgkey = %d\n",msgkey);
	}

	/*獲取消息隊列標識符*/
	//if((qid = msgget(msgkey, IPC_CREAT|0660)) == -1)
	if((qid = msgget(3739636, IPC_CREAT|0660)) == -1)		//此處將寫入消息時的msgkey值硬編碼到msgget函數中
	{
		perror ("msgget error!\n");
		exit (1);
	}

	msglen = sizeof(struct mymsgbuf) - 4;
	if (msgrcv(qid, &msgbuffer, msglen, 3, 0) == -1)  /*讀取數據*/
	{
		perror ("msgrcv error!\n");
		exit (1);
	}
	printf("Get message %s\n", msgbuffer.ctrlstring);

	exit(0);
}

現在的運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章