io模型_io多路复用_select poll epoll

应用层.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
int main(int argc, char const *argv[])
{int fd1, fd2;char buf[128] = {0};// 打开文件fd1 = open("/dev/mycdev", O_RDWR);if (fd1 < 0){printf("打开设备文件失败\n");exit(-1);}fd2 = open("/dev/input/mouse0", O_RDWR);if (fd2 < 0){printf("打开鼠标设备文件失败\n");exit(-1);}// 创建读事件集合fd_set readfds;while (1){// 清空集合FD_ZERO(&readfds);// 添加文件描述符到事件集合FD_SET(fd1, &readfds);FD_SET(fd2, &readfds);// 阻塞等待事件发生int ret = select(fd2 + 1, &readfds, NULL, NULL, NULL);if (ret < 0){printf("select调用失败\n");return ret;}// 判断要监听的事件是否发生if (FD_ISSET(fd1, &readfds)){memset(buf, 0, sizeof(buf));read(fd1, buf, sizeof(buf));printf("自定义设备事件发生buf:%s\n", buf);}if (FD_ISSET(fd2, &readfds)){memset(buf, 0, sizeof(buf));read(fd2, buf, sizeof(buf));printf("鼠标设备事件发生buf:%s\n", buf);}}close(fd1);close(fd2);return 0;
}

 模拟自定义事件硬件数据到达的进程.c

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>int main(int argc, char const *argv[])
{int a,b;char buf[128]="hello world";int fd=open("/dev/mycdev",O_RDWR);if(fd<0){printf("打开设备文件失败\n");exit(-1);}write(fd,buf,sizeof(buf));close(fd);return 0;
}

驱动.c

#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/io.h>
#include<linux/device.h>
#include<linux/uaccess.h>
#include<linux/poll.h>struct class *cls;
struct device *dev;unsigned int major;//定义一个变量保存主设备号
char kbuf[128]={0};//定义等待队列头
wait_queue_head_t wq_head;
int condition=0;//数据是否准备好的标志变量//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);if(size>sizeof(kbuf))//用户的需求内核满足不了{size=sizeof(kbuf);}long ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user filed\n");return -EIO;}condition=0;//表示下一次数据没有准备好return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);if(size>sizeof(kbuf))//用户的需求内核满足不了{size=sizeof(kbuf);}long ret;ret=copy_from_user(kbuf,ubuf,size);//表示模拟硬件数据就绪if(ret){printk("copy_from_user filed\n");return -EIO;}condition=1;wake_up_interruptible(&wq_head);//唤醒休眠的进程return 0;
}//封装poll方法
__poll_t mycdev_poll(struct file *file, struct poll_table_struct *wait)
{__poll_t mask=0;//1.向上提交等待队列头poll_wait(file,&wq_head,wait);//2.根据事件是否发生给一个合适的返回值if(condition){mask=POLLIN;}return mask;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={.open=mycdev_open,.release=mycdev_close,.read=mycdev_read,.poll=mycdev_poll,.write=mycdev_write,
};
static int __init mycdev_init(void)
{//初始化等待队列头init_waitqueue_head(&wq_head);//注册字符设备驱动major=register_chrdev(0,"mychrdev",&fops);if(major<0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功major=%d\n",major);// 向上提交目录cls = class_create(THIS_MODULE, "myled");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");// 向上提交设备节点信息dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(dev);}printk("向上提交设备节点成功\n");return 0;
}
static void __exit mycdev_exit(void)
{// 销毁节点信息device_destroy(cls, MKDEV(major, 0));// 销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychrdev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

***********epoll***************

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>#include <sys/wait.h>
#include <sys/ioctl.h>#include <sys/select.h>#include <sys/epoll.h>
/* According to earlier standards */
#include <sys/time.h>
#include"myled.h"int main(int argc, char const *argv[])
{int fd1,fd2,epfd;struct epoll_event event;struct epoll_event events[10];//存放就绪事件描述符的数组char buf[128]={0};
//创建epoll句柄
epfd=epoll_create(1);
if(epfd<0)
{printf("epoll_create filed\n");exit(-1);
}
//打开设备文件fd1=open("/dev/input/mouse0",O_RDWR);if(fd1<0){printf("打开鼠标设备文件失败\n");exit(-1);}fd2=open("/dev/my_led0",O_RDWR);if(fd2<0){printf("打开鼠标设备文件失败\n");exit(-1);}//添加准备就绪事件进入epoll;event.events=EPOLLIN;//读事件event.data.fd=fd1;if(epoll_ctl(epfd,EPOLL_CTL_ADD,fd1,&event)<0){printf("epoll_ctl add filed\n");}event.events=EPOLLIN;//读事件event.data.fd=fd2;if(epoll_ctl(epfd,EPOLL_CTL_ADD,fd2,&event)<0){printf("epoll_ctl add filed\n");}//监听事件是否发生while(1){//如果成功,ret接收返回的事件个数,把就绪的事件放在events数组中int ret=epoll_wait(epfd,events,10,-1);if(ret<0){printf("epoll_wait filed\n");exit(-1);}int i;//循环遍历数组,做事件的处理for(i=0;i<ret;i++){if(events[i].events&EPOLLIN){read(events[i].data.fd,buf,sizeof(buf));printf("buf:%s\n",buf);}}}close(fd1);close(fd2);return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MFC动态创建控件与建立消息响应

以动态创建按钮为例,新建MFC工程 在解决方案管理器,Resource.h中编辑,添加一个IDC_BUTTON0的资源ID #define IDM_ABOUTBOX 0x0010 #define IDD_ABOUTBOX 100 #define IDS_ABOUTBOX 101

【Java面试丨企业场景】常见技术场景

一、单点登录怎么实现的 1. 介绍 单点登录&#xff08;Single Sign On&#xff0c;SSO&#xff09;&#xff1a;只需要登录一次&#xff0c;就可以访问所有信任的应用系统 2. 解决方案 JWT解决单点登录问题 用户访问应用系统&#xff0c;会在网关判断Token是否有效如果Tok…

Git的安装以及本地仓库的创建和配置

文章目录 1.Git简介2.安装Git2.1在Centos上安装git2.2 在ubuntu上安装git 3.创建本地仓库4.配置本地仓库 1.Git简介 Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理文件的更改。它可以记录和存储代码的所有历史版本&#xff0c;并可以方便地进行分支管理、合并代码和协…

leetcode 1372. 二叉树中的最长交错路径

给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。 如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&#xff0c;否则移动到它的左子节点。 改变前进方向&a…

python-pytorch基础之神经网络分类

这里写目录标题 生成数据函数定义数据集定义loader加载数据定义神经网络模型测试输出是否为2个输入数据&#xff0c;输出结果 训练模型函数计算正确率 训练数据并保存模型测试模型准备数据加载模型预测对比结果 生成数据函数 import randomdef get_rectangle():widthrandom.ra…

Pytorch气温预测实战

数据集 数据有8个特征&#xff0c;一个标签值 自变量因变量yearactual:当天的真实最高温度monthdayweek:星期几temp_1:昨天的最高温度temp_2:前天的最高温度值average:在历史中&#xff0c;每年这一天的平均最高温度friend:朋友猜测的温度 year,month,day,week,temp_2,temp_…

WPF基础知识

WPF布局基础原则 1.一个窗口中只能包含一个元素 2. 不应该显示设置元素尺寸 3. 不应使用坐标设置元素的位置 4.可以嵌套布局容器WPF布局容器 StackPanel:水平或垂直排列元素&#xff0c;Orientation属性分别为&#xff1a;Horizontal/VerticalWrapPanel:水平或垂直排列元素、…

安科瑞能源物联网以能源供应、能源管理、设备管理、能耗分析的能源流向为主线-安科瑞黄安南

摘要&#xff1a;随着科学技术的发展&#xff0c;我国的物联网技术有了很大进展。为了提升电力抄表服务的稳定性&#xff0c;保障电力抄表数据的可靠性&#xff0c;本文提出并实现了基于物联网的智能电力抄表服务平台&#xff0c;结合云计算、大数据等技术&#xff0c;提供电力…

Codeforces Round 888 (Div. 3)(视频讲解全部题目)

[TOC](Codeforces Round 888 (Div. 3)&#xff08;视频讲解全部题目&#xff09;) Codeforces Round 888 (Div. 3)&#xff08;A–G&#xff09;全部题目详解 A Escalator Conversations #include<bits/stdc.h> #define endl \n #define INF 0x3f3f3f3f using namesp…

mars3d绘制区域范围(面+边框)

1、图例&#xff08;绿色面区域白色边框&#xff09; 2、代码 1&#xff09;、绘制区域ts文件 import { mapLayerCollection } from /hooks/cesium-map-init /*** 安全防護目標* param map*/ export const addSafetyProtection async (map) > {const coverDatas await m…

20230729 git github gitee

1.gitee与gitHub概念&#xff1f; Gitee&#xff08;码云&#xff09;是开源中国社区推出的代码托管协作开发平台&#xff0c;支持Git和SVN&#xff0c;提供免费的私有仓库托管。Gitee专为开发者提供稳定、高效、安全的云端软件开发协作平台&#xff0c;无论是个人、团队、或是…

6个ChatGPT4的最佳用途

文章目录 ChatGPT 4’s Current Limitations ChatGPT 4 的当前限制1. Crafting Complex Prompts 制作复杂的提示2. Logic Problems 逻辑问题3. Verifying GPT 3.5 Text 验证 GPT 3.5 文本4. Complex Coding 复杂编码5.Nuanced Text Transformation 细微的文本转换6. Complex Kn…

web前端如何判断自己当前的职业等级

初级前端开发工程师 熟练使用HTML标签&#xff0c;对HTML标签特性有一定理解。对HTML语义话有一定了解&#xff1b;熟练使用CSS属性及选择器&#xff0c;能使用一些CSShack。对模块化和栅格化布局有一定的了解。能独立使用JS完成一些简单的需求&#xff0c;至少能使用一种前端框…

P5727 【深基5.例3】冰雹猜想

【深基5.例3】冰雹猜想 题目描述 给出一个正整数 n n n&#xff0c;然后对这个数字一直进行下面的操作&#xff1a;如果这个数字是奇数&#xff0c;那么将其乘 3 3 3 再加 1 1 1&#xff0c;否则除以 2 2 2。经过若干次循环后&#xff0c;最终都会回到 1 1 1。经过验证很…

Windows下安装HBase

Windows下安装HBase 一、HBase简介二、HBase下载安装包三、环境准备3.1、 JDK的安装3.2、 Hadoop的安装 四、HBase安装4.1、压缩包解压为文件夹4.2、配置环境变量4.3、%HBASE_HOME%目录下新建临时文件夹4.4、修改配置文件 hbase-env.cmd4.4.1、配置JAVA环境4.4.2、set HBASE_MA…

使用Hutool工具类中的BeanUtil.fillBeanWithMap方法报错`DateException`

使用Hutool工具类中的BeanUtil.fillBeanWithMap方法报错DateException 问题背景 在实现登录功能时&#xff0c;我先将用户信息存入Redis中&#xff0c;然后再获取用户信息的时候&#xff0c;又取出来。我存入Redis的用户信息是Hash格式的&#xff0c;所以取出来的时候&#xff…

Ansible的脚本 --- playbook 剧本

文章目录 一、playbook剧本的组成创建剧本运行playbook二、定义、引用变量三、指定远程主机sudo切换用户四、when条件判断五、迭代Templates 模块tags 模块 一、playbook剧本的组成 playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0…

kubernetes 证书更新

参考&#xff1a; https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/https://kubernetes.io/zh-cn/docs/tasks/tls/certificate-rotation/ 查看证书 查看 kubelet是否支持证书自动轮换&#xff0c;默认轮换的证书位于目录 /var/lib/kubele…

vscode 打开文件时如何在资源管理器中展开文件所在的整个目录树(包含node_modules)

如题。去 首选项 --> 设置 中 搜索 “Auto Reveal”&#xff0c;然后选true&#xff0c;注意把下面的Auto Reveal Exclude排除项中的node_modules去掉&#xff0c;这样才能定位到node_modules中的文件。 **/node_modules

正则,JS:this,同步异步,原型链笔记整理

一 正则表达式 正则表达式&#xff08;regular expression&#xff09;是一种表达文本模式&#xff08;即字符串结构&#xff09;的方法&#xff0c;有点像字符串的模板&#xff0c;常常用来按照“给定模式”匹配文本 正则表达式可以用于以下常见操作&#xff1a; 匹配&…