将poll程序改为epoll实现
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,原实例在APUE(第三版)17.2 UNIX域套接字1、使用UNIX与套接字轮询XSI消息队列(poll版,原版)#include "apue.h"#include #include #include
千家信息网最后更新 2026年11月01日将poll程序改为epoll实现
原实例在APUE(第三版)17.2 UNIX域套接字
1、使用UNIX与套接字轮询XSI消息队列(poll版,原版)
#include "apue.h"#include#include #include #include #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#include #include #include #define NQ 3 //队列的数量#define MAXMSZ 512 //消息的最大长度#define KEY 0x123 //消息队列的第一个key值#define FDSIZE 1000#define EPOLLEVENTS 100struct 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#define MAXMSZ 512struct 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:0xX\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 ***
队列
消息
套接字
命令
编译
最大
事件
原版
数量
管道
线程
长度
程序
之间
函数
原文
实例
文件
笔记
测试
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技企业
A股互联网金融科技公司
互联网科技深圳
互联网科技会
互联网科技资迅
深圳互联网科技公司
金融科技 互联网金融
互联网金融 金融科技
互联网金融 科技金融
顺玮阁互联网科技
兼蜜互联网科技
中国科技互联网公司收入
互联网系的金融科技公司
现代互联网科技股
互联网时代科技改变生活
互联网新科技动漫ppt素材
如何创新互联网科技
广东工业互联网大赛深圳学泰科技
众联互联网络科技
现代互联网科技公司
什么是科技互联网
互联网属科技
金融科技 互联网金融
广州互联网络科技有限公司
奇酷互联网络科技公司
融势互联网科技
科技赋能视角下互联网保险发展
南京一网一红互联网科技有限公司
西安有哪些互联网高科技企业
世界互联网科技成果奖