消息:ftok(), msgget(), msgsnd(),msgrcv(),msgctl()

/*
 * msgsnd.c
 *
 *  Created on: 2012-7-20
 *      Author: liwei.cai
 */
//以下是消息队列发送端的代码,与接收端配合使用,
//输入字符串quit时退出程序,其他字符串发送

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

#define BUFFER_SIZE 512

struct message
{
	long msg_type;
	char msg_text[BUFFER_SIZE];
};

int main()
{
	int qid;
	key_t key;
	struct message msg;
	/*根据不同的路径和关键字产生标准的 key*/
	 if ((key = ftok(".", 'a')) == -1)
	{
		perror("ftok");
		exit(1);
	}
	/*创建消息队列*/
	if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
	{
		perror("msgget");
		exit(1);
	}
	printf("Open queue %d\n",qid);
	while(1)
	{
		printf("Enter some message to the queue:");

		if ((fgets(msg.msg_text, BUFFER_SIZE, stdin)) == NULL)
		{
			puts("no message");
			exit(1);
		}

		msg.msg_type = getpid();

		 /*添加消息到消息队列*/
		if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)//阻塞直到发送成功
		{
			perror("message posted");
			exit(1);
		}

		if (strncmp(msg.msg_text, "quit", 4) == 0)
		{
			break;
		}
	}
	exit(0);
}


/*
 * msgrcv.c
 *
 *  Created on: 2012-7-20
 *      Author: liwei.cai
 */
//以下是消息队列接收端的代码,与发送端配合使用
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 512

struct message
{
	long msg_type;
	char msg_text[BUFFER_SIZE];
};
int main()
{
	int qid;
	key_t key;
	struct message msg;

	/*根据不同的路径和关键字产生标准的 key*/
	if ((key = ftok(".", 'a')) == -1)
	{
		perror("ftok");
		exit(1);
	}

	/*创建消息队列*/
	if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
	{
		perror("msgget");
		exit(1);
	}

	printf("Open queue %d\n", qid);

	do
	{
	  /*读取消息队列*/
		memset(msg.msg_text, 0, BUFFER_SIZE);
	  if (msgrcv(qid, (void*)&msg, BUFFER_SIZE, 0, 0) < 0) //阻塞知道接受到一条消息后为止
	  {
		  perror("msgrcv");
		  exit(1);
	  }
	  printf("The message from process %ld:%s",msg.msg_type,msg.msg_text);//显示接受到的消息
	}
	while(strncmp(msg.msg_text, "quit", 4));
	 /*从系统内核中移走消息队列 */
	if ((msgctl(qid, IPC_RMID, NULL)) < 0)
	{
	  perror("msgctl");
	  exit(1);
	}
	exit(0);
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用上述系统调用编写的消息队列发送和接收程序的示例: 发送程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_MSG_SIZE 1024 struct msg_buffer { long msg_type; char msg_text[MAX_MSG_SIZE]; }; int main() { key_t key = ftok(".", 'a'); // 生成一个key int msg_id = msgget(key, IPC_CREAT | 0666); // 创建或打开消息队列 if (msg_id == -1) { perror("msgget"); exit(EXIT_FAILURE); } struct msg_buffer msg; msg.msg_type = 1; printf("Enter a message to send: "); fgets(msg.msg_text, MAX_MSG_SIZE, stdin); // 从标准输入读取消息内容 if (msgsnd(msg_id, &msg, sizeof(msg.msg_text), 0) == -1) { // 发送消息 perror("msgsnd"); exit(EXIT_FAILURE); } printf("Message sent successfully!\n"); return 0; } ``` 接收程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_MSG_SIZE 1024 struct msg_buffer { long msg_type; char msg_text[MAX_MSG_SIZE]; }; int main() { key_t key = ftok(".", 'a'); // 使用同样的key获取消息队列 int msg_id = msgget(key, IPC_CREAT | 0666); // 创建或打开消息队列 if (msg_id == -1) { perror("msgget"); exit(EXIT_FAILURE); } struct msg_buffer msg; if (msgrcv(msg_id, &msg, sizeof(msg.msg_text), 1, 0) == -1) { // 接收消息 perror("msgrcv"); exit(EXIT_FAILURE); } printf("Received message: %s", msg.msg_text); return 0; } ``` 这两个程序可以在不同的终端窗口中分别启动。发送程序会提示用户输入一条消息,然后将该消息发送到消息队列中;接收程序会从消息队列中接收一条消息并显示在终端上。 控制消息队列的系统调用包括: - msgget:创建或打开一个消息队列。 - msgsnd:向消息队列发送一条消息。 - msgrcv:从消息队列接收一条消息。 - msgctl:控制消息队列的属性,如删除消息队列等。 这些系统调用都需要使用 key_t 类型的 key 来标识消息队列。key 可以使用 ftok 函数生成,也可以手动指定。在使用 msgget 函数创建消息队列时,需要指定标志参数,比如 IPC_CREAT 表示创建新队列,IPC_EXCL 表示如果队列已经存在则返回错误。在使用 msgsnd 函数发送消息时,需要指定消息类型、消息内容和消息长度。在使用 msgrcv 函数接收消息时,需要指定要接收的消息类型和接收缓冲区的大小。在使用 msgctl 函数控制消息队列时,需要指定要控制的队列标识符和要执行的操作,比如删除队列、修改队列属性等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值