UNIX域套接字轮询XSI消息队列

30 篇文章 2 订阅
4 篇文章 0 订阅
/*
轮询实现。
因为消息队列和文件描述符没有关联,利用unix域套接字的作为中间层。
*/
#include <unistd.h>
#include <pthread.h>
#include <poll.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/msg.h>

const int NQ = 3;
const int MAXSZ = 512;
const int KEY = 0x1230;

// 线程函数参数结构体
struct threadinfo
{
	int qid;
	int fd;
};

// 消息队列结构体,XSI消息的固定结构方式
struct mymesg			// message list's data struct , must be it.
{
	long mbyte;
	char text[MAXSZ];
};

// extern "C"
// {
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
//                           void *(*start_routine) (void *), void *arg);
// }
void *procmsg(void *p)
{
	struct mymesg m;
	struct threadinfo *ti = (struct threadinfo *)p;
	int nRead;
	for (;;)
	{
		memset(&m, 0, sizeof(m));
                // 从指定ID的队列中获取一个消息,一直阻塞到有消息到
                if ((nRead = msgrcv(ti->qid, &m, MAXSZ, 0, MSG_NOERROR)) < 0)
		{
			write(STDERR_FILENO, "msgrcv error", 12);
			exit(-1);
		}
               // 向套接字写,通知父线程
               if ((nRead = write(ti->fd, m.text, nRead)) < 0)
		{
			write(STDERR_FILENO, "write error", 11);
			exit(-1);
		}
	}
}

int main(int argc, char *argv[])
{
	int fd[2];
	struct threadinfo ti[NQ];
	pthread_t tid[NQ];
	struct pollfd pollfd[NQ];
	char buf[MAXSZ];

	for (int i = 0; i < NQ;++i)
	{
               // 创建消息队列,KEY随机指定
                if ((ti[i].qid = msgget(KEY+i, IPC_CREAT | 0666)) < 0)
		{
			write(STDERR_FILENO, "msgget error", 12);
			exit(-1);			
		}

		memset(buf, 0, MAXSZ);
		sprintf(buf, "[%d]queue:%d\n", i, ti[i].qid);
		write(STDOUT_FILENO, buf, strlen(buf));

               // fd[0],fd[1]可读可写
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0)
		{
			write(STDERR_FILENO, "socketpair error", 16);
			exit(-1);
		}

		ti[i].fd = fd[0];
		pollfd[i].fd = fd[1];
		pollfd[i].events = POLLIN;

		if (pthread_create(&tid[i], NULL, procmsg, &ti[i]) != 0)
		{
			write(STDERR_FILENO, "pthread_create error", 20);
			exit(-1);
		}
	}

	char qbuf[MAXSZ];
	for (;;)
	{
		if (poll(pollfd, NQ, -1) < 0)	// INFTIM
		{
			write(STDERR_FILENO, "poll error", 10);
			exit(-1);
		}
		for (int i = 0; i < NQ; ++i)
		{
			if (pollfd[i].revents & POLLIN)
			{
				int nRead = read(pollfd[i].fd, buf, MAXSZ);
				if (nRead < 0)
				{
					write(STDERR_FILENO, "read error", 10);
					exit(-1);
				}
				buf[nRead] = '\0';
				memset(qbuf, 0, sizeof(qbuf));
				sprintf(qbuf, "[%d]queue recv:%s\n", ti[i].qid, buf);
				write(STDOUT_FILENO, qbuf, strlen(qbuf));
			}
		}
	}

	return 0;
}


/*
测试文件。
*/

#include <sys/socket.h>
#include <poll.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

const int MAXSZ = 512;

struct mymesg
{
	long mbyte;
	char text[MAXSZ];
};

int main(int argc, char *argv[])
{
	key_t key;
	long qid;
	if (argc != 3)
	{
		write(STDERR_FILENO, "Usage:./exe [keyid] [msg]\n", 26);
		exit(-1);
	}
	key = strtol(argv[1], NULL, 0);
	if ((qid = msgget(key, 0)) < 0)
	{
		write(STDERR_FILENO, "msgget error\n", 13);
		exit (-1);
	}

	struct mymesg m;
	memset(&m, 0, sizeof(m));
	strncpy(m.text, argv[2], strlen(argv[2]));
	m.mbyte = 1;
	if (msgsnd(qid, &m, strlen(m.text), 0) < 0)
	{
		write(STDERR_FILENO, "msgsnd error\n", 12);
		exit(-1);
	}
	return 0;
}

     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值