将poll程序改为epoll实现
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,原实例在APUE(第三版)17.2 UNIX域套接字1、使用UNIX与套接字轮询XSI消息队列(poll版,原版)#include "apue.h"#include #include #include
千家信息网最后更新 2025年12月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安全错误
数据库的锁怎样保障安全
软件开发人员 能力
关闭数据库应用程序
网络安全的技术理论
大型工控软件开发
1.16.5粘液科技服务器
网络安全法是什么实施
模块化服务器机房
pandas 导入数据库
畅游的游戏服务器在哪里的
湖南软件开发培训费用
湖州软件开发驻场咨询
国内有名的软件开发商
java 多线程 服务器
怎么防止服务器进入ddos
统一软件开发过程 ppt
win7客户端软件开发
网络安全作业.
qq怎么断开远程连接服务器
网络安全风险隐患重要信息
用c 写数据库
网络安全开展应急预案演练
汤森路透数据库
软件开发项目经理前景
软件开发公司资质咨询
远方网络技术有限公司
我的方舟为什么不显示服务器
公司网络安全建设发言稿
贵州计算机网络安全
配置文件连接到数据库连接
我国自主研发的无线网络技术