中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

將poll程序改為epoll實現

發布時間:2020-06-20 08:41:00 來源:網絡 閱讀:1390 作者:RQSLT 欄目:系統運維

原實例在APUE(第三版)17.2 UNIX域套接字


1、使用UNIX與套接字輪詢XSI消息隊列(poll版,原版)

#include "apue.h"
#include <poll.h>
#include <pthread.h>
#include <sys/msg.h>
#include <sys/socket.h>

#define NQ			3		//隊列的數量
#define MAXMSZ		512		//消息的最大長度
#define KEY			0x123	//消息隊列的第一個key值

struct threadinfo {
	int qid;
	int fd;
};

struct mymesg {
	long mtype;
	char mtext[MAXMSZ];
};

void *helper(void *arg)
{
	int n;
	struct mymesg m;
	struct threadinfo *tip = arg;

	for (;;) {
		printf("helper qid %d, fd %d, tid %u\n", tip->qid, tip->fd, (unsigned)pthread_self());

		memset(&m, 0, sizeof(m));
		if ((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0) {
			err_sys("msgrcv error");
		}
		if (write(tip->fd, m.mtext, n) < 0) {
			err_sys("write error");
		}
	}
}
int main()
{
	int i, n, err;
	int fd[2];
	int qid[NQ];
	struct pollfd pfd[NQ];
	struct threadinfo ti[NQ];
	pthread_t tid[NQ];
	char buf[MAXMSZ];

	for (i = 0; i < NQ; ++i) {
		if ((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) < 0) {	//創建一個新隊列
			err_sys("msgget error");
		}
		printf("queue %d ID is %d\n", i, qid[i]);
		if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) {	//創建UNXI域套接字(fd管道)
			err_sys("socketpair error");
		}
		printf("fd[0]:%d\n", fd[0]);
		printf("fd[1]:%d\n", fd[1]);
		pfd[i].fd = fd[0];
		pfd[i].events = POLLIN;
		ti[i].qid = qid[i];
		ti[i].fd = fd[1];
		if ((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0) {	//創建線程
			err_exit(err, "pthread_create error");
		}
	}

	for (;;) {
		if (poll(pfd, NQ, -1) < 0) {	//等待事件發生
			err_sys("poll error");
		}
		for (i = 0; i < NQ; ++i) {
			//printf("i:%d\n", i);
			if (pfd[i].revents & POLLIN) {
				if ((n = read(pfd[i].fd, buf, sizeof(buf))) < 0) {
					err_sys("read error");
				}
				buf[n] = 0;
				printf("queue %d id %d, message %s\n", i, qid[i], buf);
			}
		}
	}
	exit(0);
}

編譯命令:

gcc pollmsg.c -o pollmsg -lapue -lpthread -std=c99

2、使用UNIX與套接字輪詢XSI消息隊列(epoll版,改版)

#include "apue.h"
#include <pthread.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define NQ			3		//隊列的數量
#define MAXMSZ		512		//消息的最大長度
#define KEY			0x123	//消息隊列的第一個key值
#define FDSIZE		1000
#define EPOLLEVENTS	100

struct threadinfo {
	int qid;
	int fd;
};

struct mymesg {
	long mtype;
	char mtext[MAXMSZ];
};

void *helper(void *arg)
{
	int n;
	struct mymesg m;
	struct threadinfo *tip = arg;

	for (;;) {
		printf("helper qid %d, fd %d, tid %u\n", tip->qid, tip->fd, (unsigned)pthread_self());

		memset(&m, 0, sizeof(m));
		if ((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0) {
			err_sys("msgrcv error");
		}
		if (write(tip->fd, m.mtext, n) < 0) {
			err_sys("write error");
		}
	}
}

int main()
{
	int i, n, err;
	int fd[2];
	int qid[NQ];
	int epollfd;
	struct epoll_event events[EPOLLEVENTS];
	struct threadinfo ti[NQ];
	pthread_t tid[NQ];
	char buf[MAXMSZ];

	epollfd = epoll_create(FDSIZE);	//創建epoll文件描述符

	for (i = 0; i < NQ; ++i) {
		if ((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) < 0) {	//創建一個新隊列
			err_sys("msgget error");
		}
		printf("queue %d ID is %d\n", i, qid[i]);
		if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) {	//創建UNXI域套接字(fd管道)
			err_sys("socketpair error");
		}
		struct epoll_event ev;
		ev.events = EPOLLIN;
		ev.data.fd = fd[0];
		epoll_ctl(epollfd, EPOLL_CTL_ADD, fd[0], &ev);	//注冊fd[0]到epoll
		ti[i].qid = qid[i];
		ti[i].fd = fd[1];
		if ((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0) {	//創建線程
			err_exit(err, "pthread_create error");
		}	
	}

	for (;;) {
		int occurred;
		if ((occurred = epoll_wait(epollfd, events, EPOLLEVENTS, -1)) < 0) {	//等待事件發生
			err_sys("epoll error");
		}
		if (occurred == 0) {
			err_sys("epoll timeout");
		}

		for (i = 0; i < occurred; ++i) {
			if (events[i].events & EPOLLIN) {
				if ((n = read(events[i].data.fd, buf, sizeof(buf))) < 0) {
					err_sys("read error");
				}
				buf[n] = 0;
				printf("main thread %u, message %s\n", (unsigned)pthread_self(), buf);
			}
		}

	}
	exit(0);
}

編譯命令:

gcc epollmsg.c -o epollmsg -lapue -lpthread -std=c99

3、給XSI消息隊列發送消息(測試程序,原版)

#include "apue.h"
#include <sys/msg.h>

#define MAXMSZ 512

struct mymesg {
	long mtype;
	char mtext[MAXMSZ];
};

int main(int argc, char *argv[])
{
	key_t key;
	long qid;
	size_t nbytes;
	struct mymesg m;

	if (argc != 3) {
		fprintf(stderr, "usage: sendmsg KEY message\n");
		exit(1);
	}

	key = strtol(argv[1], NULL, 0);
	//printf("key:0x%08X\n", (unsigned )key);
	if ((qid = msgget(key, 0)) < 0) {	//打開一個現有隊列
		err_sys("can't open queue key %s", argv[1]);
	}
	memset(&m, 0, sizeof(m));
	strncpy(m.mtext, argv[2], MAXMSZ - 1);
	nbytes = strlen(m.mtext);
	m.mtype = 1;
	//printf("qid:%ld\n", qid);
	if (msgsnd(qid, &m, nbytes, 0) < 0) {	//發送消息給指定消息隊列
		err_sys("can't send message");
	}
	exit(0);
}

編譯命令:

gcc sendmsg.c -o sendmsg -lapue -std=c99


相關閱讀:

1、select、poll、epoll之間的區別總結[整理]

2、poll函數的使用,原文

3、APUE讀書筆記


*** walker ***


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

渭南市| 巩义市| 陆良县| 顺平县| 淮阳县| 沙坪坝区| 九龙坡区| 古蔺县| 始兴县| 铜鼓县| 徐闻县| 湖北省| 疏附县| 宜宾市| 玉山县| 陆河县| 盐城市| 资阳市| 秭归县| 宝兴县| 张家口市| 大埔区| 彰武县| 湾仔区| 禹州市| 长丰县| 芷江| 如皋市| 左贡县| 汾西县| 台州市| 麻城市| 二手房| 介休市| 拜泉县| 白水县| 诸暨市| 司法| 仙桃市| 左权县| 扶风县|