poll

libusb_bulk_transfer 异步同步

不想你离开。 提交于 2019-12-02 21:33:04
同步方式 libusb_bulk_transfer(devh, ep_bulk, buf, CAM_BUF_SZ, &len, timeout); 进入libusb研究,发现libusb是采用异步方式来实现的。在do_sync_bulk_transfer中: static int do_sync_bulk_transfer ( struct libusb_device_handle * dev_handle , unsigned char endpoint , unsigned char * buffer , int length , int * transferred , unsigned int timeout , unsigned char type ) { libusb_fill_bulk_transfer ( transfer , dev_handle , endpoint , buffer , length , bulk_transfer_cb , & completed , timeout ); transfer -> type = type ; r = libusb_submit_transfer ( transfer ); if ( r < 0 ) { libusb_free_transfer ( transfer ); return r ; } while (!

Linux设备驱动程序 之 poll和select

风格不统一 提交于 2019-12-02 19:34:31
使用非阻塞IO的应用程序经常使用select,poll,epoll系统调用;它们的功能本质上是一样的:都允许进程决定是否可以对一个或者多个打开的文件做非阻塞的读取或者写入;这些电泳也会阻塞进程,直到给定的文件描述符中的任何一个可读取或者写入;因此,它们常常用于那些需要使用多个输入或者输出流而又不会阻塞于其中任何一个流的应用程序中;同一功能之所以要由多个独立的函数提供,是因为其中两个几乎是由两个不同的Unix团体分别实现的:select在BSD中引入,而poll由SystemV引入;epoll系统调用则用于将poll函数扩展到能够处理数千个文件描述符; poll在file_operations结构中的定义如下: 1 unsigned int (*poll) (struct file *, struct poll_table_struct *); 1 unsigned int ( * poll ) ( struct file * , struct poll_table_struct * ) ; 当用户空间程序在驱动程序关联的文件描述符上执行select,poll,epoll系统调用时,该驱动程序的方法将被调用;该poll函数的功能分为两步: 1. 在一个或者多个可指示poll状态变化的等待队列上调用poll_wait;如果当前没有文件描述符可用来执行IO

eventfd(2) 结合 select(2) 分析

好久不见. 提交于 2019-12-02 18:46:18
本文代码选自内核 4.17 eventfd(2) - 创建一个文件描述符用于事件通知。 使用 源码分析 参考 #include <sys/eventfd.h> int eventfd(unsigned int initval, int flags); int eventfd2(unsigned int initval, int flags); 参数 - \initval 为初始值(关联内部结构的 count) - \flags 内核 2.6.26 之前的版本这个参数无效且必须指定为 0 flags 有意义的参数为 - EFD_CLOEXEC, 等效于 O_CLOEXEC - EFD_NONBLOCK, 等效于 O_NONBLOCK - EFD_SEMAPHORE, 信号量选项,影响 read(2) 的取值 返回 - 成功返回一个新的文件描述符,失败返回 -1 并设置 errno eventfd 作为一个非常简单的抽象文件,每个文件描述符都对应一个在内核空间维护的 __u64 count , 一个无符号64位整形的计数器,而eventfd对应的文件操作都与这个计数器相关。 提供的文件操作 read(2), 读取 count 减少的值,若flags设置 EFD_SEMAPHORE 则 count -= 1 , 否则 count -= count ; 函数成功返回 8 write(2),

用两个队列实现栈的操作

牧云@^-^@ 提交于 2019-12-02 15:06:39
public class MyStack<E> { private Queue<E> Q1=new LinkedList<>(); private Queue<E> Q2=new LinkedList<>(); public E push(E e){ if(Q1.isEmpty()&&Q2.isEmpty()){ Q1.add(e); } if(Q1.isEmpty()){ Q2.add(e); } if(Q2.isEmpty()){ Q1.add(e); } return e; } public E pop(){ if(Q1.isEmpty()&&Q2.isEmpty()){ try { throw new Exception("the stack is empty"); }catch (Exception e){ e.printStackTrace(); } } if(Q1.isEmpty()){ while (Q2.size()>1){ Q1.add(Q2.poll()); } return Q2.poll(); } if(Q2.isEmpty()){ while (Q1.size()>1){ Q2.add(Q1.poll()); } return Q1.poll(); } return null; } public E peek(){ if(Q1.isEmpty()&&Q2

epoll(2) 使用及源码分析的引子

北城余情 提交于 2019-12-02 11:47:30
epoll(2) 使用及源码分析的引子 本文代码取自内核版本 4.17 epoll(2) - I/O 事件通知设施。 epoll 是内核在2.6版本后实现的,是对 select(2)/poll(2) 更高效的改进,同时它自身也是一种文件,不恰当的比方可以看作 eventfd + poll。 多路复用也是一直在改进的,经历的几个阶段 select(2) - 只能关注 1024 个文件描述符,并且范围固定在 0 - 1023,每次函数调用都需要把所有关注的数据复制进内核空间,再对所有的描述符集合进行遍历判断。 poll(2) - 改进 select(2) 前面两个缺点,可以自定义关注的描述符,数量也不受限制(不超过系统的限制),每次调用同样需要复制所有的事件进内核空间,全部遍历。 epoll(2) - 不需要每次调用时所有关注的文件描述符进行内核-用户空间的复制,而是直接将所有的文件描述符和事件常驻内核空间,同时也不需要每次遍历所有文件描述符。 提供的系统调用 #include <sys/epoll.h> typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll

IO复用一select, poll, epoll用法说明

…衆ロ難τιáo~ 提交于 2019-12-02 11:02:21
三种IO复用类型 Select系统调用 #include<sys/select.h> int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* execptfds,struct timeval* timeout); #nfds表示监听的文件描述符总数; #readfds,writefds,execptfds分别表示对应的fd_set类型的集合 可以如下定义:fd_set readfds,writefds,execptfds #timeout表示select函数的超时时间 Struct timeval { Long tv_sec; Long tv_usec; } 如果timeval成员变量均为0,则select立即返回;如果timeout设置为NULL,则select将一直阻塞,直到某个文件描述符就绪。 # FD_ZERO(fd_set *fdset);清楚fdset的所有位,如FD_ZERO(&readfds); #FD_SET(int fd,fd_set* fdset);设置fdset的位,也就是将某个文件描述符加入到fdset中,如FD_SET(0,&readfds),将标准输入加入到fdset中 #int FD_ISSET(int fd,fd_set * fdset);测试fdset的某个位是否被设置

理解I/O复用

ⅰ亾dé卋堺 提交于 2019-12-02 05:08:59
原文地址 https://blog.csdn.net/xd_rbt_/article/details/80287959 I/O复用就是单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流. 假设你是一个机场的空管, 你需要管理到你机场的所有的航线, 包括进港,出港, 有些航班需要放到停机坪等待,有些航班需要去登机口接乘客。 你会怎么做? 最简单的做法,就是你去招一大批空管员,然后每人盯一架飞机, 从进港,接客,排位,出港,航线监控,直至交接给下一个空港,全程监控。 那么问题就来了: 很快你就发现空管塔里面聚集起来一大票的空管员,交通稍微繁忙一点,新的空管员就已经挤不进来了。 空管员之间需要协调,屋子里面就1, 2个人的时候还好,几十号人以后 ,基本上就成菜市场了。 空管员经常需要更新一些公用的东西,比如起飞显示屏,比如下一个小时后的出港排期,最后你会很惊奇的发现,每个人的时间最后都花在了抢这些资源上。 现实上我们的空管同时管几十架飞机稀松平常的事情, 他们怎么做的呢? 他们用这个东西 ·这个东西叫flight progress strip. 每一个块代表一个航班,不同的槽代表不同的状态,然后一个空管员可以管理一组这样的块(一组航班),而他的工作,就是在航班信息有新的更新的时候,把对应的块放到不同的槽子里面。 这个东西现在还没有淘汰哦,只是变成电子的了而已。。

gevent协程之猴子补丁带来的坑

岁酱吖の 提交于 2019-12-02 02:05:41
我们都知道使用gevent协程时,经常会看见在导入包的时候看见这样的代码 from gevent import monkey; monkey.patch_all() monkey.patch_all()作用呢,就是将阻塞的改成非阻塞 具体有哪些呢。 Example: 执行发现报错了。loop_exit,线程异常退出。线程改成非阻塞失败。(__此问题摘自遇到此问题的一个微友) import random, datetime, time, json import gevent from gevent.pool import Pool from gevent import monkey; monkey.patch_all() import requests ywdata = [(0, '20191022', 0, 0, '1068', 1, 1, 0, 0), (1, '20181022', 0, 0, '1068', 1, 1, 0, 0), (2, '20171022', 0, 0, '1068', 1, 1, 0, 0), (3, '20161022', 0, 0, '1068', 1, 1, 0, 0), (4, '20151022', 0, 0, '1068', 1, 1, 0, 0), (5, '20141022', 0, 0, '738', 1, 1, 0, 0), (6,

基于select的网络IO模型

本秂侑毒 提交于 2019-12-01 22:28:44
#select 和 poll 和epoll的区别 ''' select和poll有一个共同的机制,都是采用轮训的方式去询问内核,有没有数据准备好了 select有一个最大监听事件的限制,32位机限制1024,,6位机限制2048 poll没有,理论上poll可以开启无限大,1G内存大概够你开10W个事件去监听 epoll是最好的,采用的是回调机制,解决了select和poll共同存在的问题 而且epoll理论上也可以开启无限多个监听事件 ''' # IO多路复用 ''' 阻塞IO 非阻塞IO 多路复用IO 异步IO python实现不了,但是有tornado框架,天生自带异步 ''' #服务器端 import socket import select sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() Conn_Del = [] #定义删除列表 rlist = [sk] #是用来让select帮忙监听的所有接口 # select:windows/linux是监听事件有没有数据到来 # poll: linux 也可以做select的工作 # epoll: linux 也可以做类似的工作 while 1: r,w,x = select.select(rlist,[],[]) #将rlist传给select

从实践角度重新理解BIO和NIO

扶醉桌前 提交于 2019-12-01 22:28:14
前言 这段时间自己在看一些Java中BIO和NIO之类的东西,看了很多博客,发现各种关于NIO的概念说的天花乱坠头头是道,可以说是非常的完整,但是整个看下来之后,自己对NIO还是一知半解的状态,所以这篇文章不会提到很多的概念,而是站在一个实践的角度,写一些我自己关于NIO的见解,站在实践过后的高度下再回去看概念,应该对概念会有一个更好的理解。 实现一个简易单线程服务器 要讲明白BIO和NIO,首先我们应该自己实现一个简易的服务器,不用太复杂,单线程即可。 为什么使用单线程作为演示 因为在单线程环境下可以很好地对比出BIO和NIO的一个区别,当然我也会演示在实际环境中BIO的所谓一个请求对应一个线程的状况。 服务端 public class Server { public static void main(String[] args) { byte[] buffer = new byte[1024]; try { ServerSocket serverSocket = new ServerSocket(8080); System.out.println("服务器已启动并监听8080端口"); while (true) { System.out.println(); System.out.println("服务器正在等待连接..."); Socket socket =