Eventlet学习总结

合集下载

workman的学习总结

workman的学习总结

workman的学习总结我们知道php主要是⽤来做web应⽤的,⽽且平时使⽤的都是都是和其他的web服务器来结合使⽤,⽐如和apache,nginx和apache的时候,是作为apache的⼀个动态模块来加载,和nginx的时候主要是使⽤fpm的形式,现在其他的⼀些语⾔,⽐如python,nodejs,ruby,go 都是单独作为http服务编程的,其实php也是可以的,php⾥⾯有⼀些扩展,我们平时做web应⽤的时候都是很少使⽤到的,⽐如fcntl,libevent,stream,posix等等,这些扩展主要是对unix的api的⼀些封装,使⽤它们其实和uinx的⽹络编程是⼀样的,只是更加的便捷和容易,还可以使⽤我们熟悉的php语⾔,⽽不是c。

workman其实就是把php的⽹络模块做⼀个整合,为php⽤户提供⼀个更加便捷的⽅式来创建⽹络编程的条件,⽐如实现tcp,udp服务器,实现http的web服务器等等。

主要的⽂件结构Worker.php 是workman的主要⼊⼝⽂件,这个定义了workman作为⼀个服务器的相关的操作,变量初始化,参数解析,进程管理,请求接受,事件注册处理等等。

WebServer.php 继承了Worker.php主要还是使⽤Worker.php的逻辑,主要区别是使⽤Htpp的协议,以及实现对uri的简单路由分发。

Events 是事件的相关类Lib 包含Timer.php 以及⼀些常数。

Connection 是对连接的处理Protocols 是对协议的处理,主要是对Connection接收的数据的处理,⽐如http的时候添加header头等等。

Worker.php的分析内部函数备注说明self::checkSapiEnv();//监测环境是否正确,workman只能运⾏在cli模式下⾯self::init();//环境初始化self::parseCommand();//解析参数,主要对应⽤start,stop,restart,status, -d的判断self::daemonize();//master进程编程daemo守护进程self::initWorkers();//初始化work进程self::installSignal();// 安装信号量self::saveMasterPid();// 保存master的进程id,⼀⽂件的形式self::forkWorkers();//fork⽣成⼦进程,在event上⾯注册请求到达的事件self::displayUI();//显⽰ui,⽤来在控制台打印输出⼀些内容self::resetStd(); //重新设置标准输出和输⼊self::monitorWorkers();// 监控⼦进程selef::checkSapiEnv//根据php_sapi_name来做判断if (php_sapi_name() != "cli") {exit("only run in command line mode \n");}sapi接⼝是php为其他的应⽤提供的抽象层接⼝,不管是cli还是php-fpm,fastCgi都是调⽤这⼀层的接⼝。

JRuleEngine学习总结

JRuleEngine学习总结

JRuleEngine学习总结高广林 2010-12-13这两天学习了一下规则引擎,选择使用JRuleEngine用于实际的应用,简介说明和规则引擎的原理说明请“Google一下”,总结一个文档,希望您对JRuleEngine的使用能更快的上手。

---------------------------------------我--是--废--话--和--正--文--的--分--割--线----------------------------------1、定义XML规则文件规则可以通过如下的两种方式加载:(1)通过XML文件进行加载(2)通过向方法LocalRuleExecutionSetProvider.createRuleExecutionSet中传入一组RuleImpl类型的参数。

2、规则定义的形式(1)名称(name)(2)描述(description)(3)一组判定对象,定义形式:"leftTerm" ["operator" "rightTerm"]。

所有的判定通过AND操作符进行连接。

如果判定以"leftTerm" "operator" "rightTerm"的形式出现,那么在左右参数之间的连接符可以是"=", "<>", "contains", "notcontains","containsatleastone", "notcontainsanyone", "<", ">", "<=", ">=",其中的最后四个仅在数值型参数中使用。

tapestry学习总结

tapestry学习总结

href="javascript:delQTZYOption('selectedQTZY')"> <font color="#FF0000">删除</font></a>&nbsp;</TD>
<td NOWRAP> <select id="selectedQTZY" name="selectedQTZY"
document.getElementById("dmWindow").style.top = eT - dH; } else {
document.getElementById("dmWindow").style.top = eT + eH; }
document.getElementById("dmWindow").style.display = "block"; document.getElementById("dmWindow").style.left = dmType_label_target.offsetLeft + dmType_label_target.offsetWidth document.getElementById("dmWindow").offsetWidth; var sURL = contextPath+"/eps/public/DmTree.html?dmid="+ dmlb+"&editType=ReadOnly"+"&allowNull="+allowNull; if(MaxJC) {

Get清风epoll学习笔记

Get清风epoll学习笔记

epoll学习笔记epoll学习笔记epoll有两种模式,Edge Triggered(简称ET) 和 Level Triggered(简称LT).在采用这两种模式时要注意的是,如果采用ET模式,那么仅当状态发生变化时才会通知,而采用LT模式类似于原来的select/poll操作,只要还有没有处理的事件就会一直通知.以代码来说明问题:首先给出server的代码,需要说明的是每次accept的连接,参加可读集的时候采用的都是ET模式,而且接收缓冲区是5字节的,也就是每次只接收5字节的数据:#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <errno.h>using namespace std;#define MAXLINE 5#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5000#define INFTIM 1000void setnonblocking(int sock){int opts;opts=fcntl(sock,F_GETFL);if(opts<0){perror("fcntl(sock,GETFL)");exit(1);}opts = opts|O_NONBLOCK;if(fcntl(sock,F_SETFL,opts)<0){perror("fcntl(sock,SETFL,opts)");exit(1);}}int main(){int i, maxi, listenfd, connfd, sockfd,epfd,nfds;ssize_t n;char line[MAXLINE];socklen_t clilen;//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件struct epoll_event ev,events[20];//生成用于处理accept的epoll专用的文件描述符epfd=epoll_create(256);struct sockaddr_in clientaddr;struct sockaddr_in serveraddr;listenfd = socket(AF_INET, SOCK_STREAM, 0);//把socket设置为非阻塞方式//setnonblocking(listenfd);//设置与要处理的事件相关的文件描述符ev.data.fd=listenfd;//设置要处理的事件类型ev.events=EPOLLIN|EPOLLET;//ev.events=EPOLLIN;//注册epoll事件epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;char *local_addr="127.0.0.1";inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);serveraddr.sin_port=htons(SERV_PORT);bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));listen(listenfd, LISTENQ);maxi = 0;for( ; ; ) {//等待epoll事件的发生nfds=epoll_wait(epfd,events,20,500);//处理所发生的所有事件for(i=0;i<nfds;++i){if(events[i].data.fd==listenfd){connfd = accept(listenfd,(sockaddr *)&clientaddr, &clil en);if(connfd<0){perror("connfd<0");exit(1);}//setnonblocking(connfd);char *str = inet_ntoa(clientaddr.sin_addr);cout << "accapt a connection from " << str << end l;//设置用于读操作的文件描述符ev.data.fd=connfd;//设置用于注测的读操作事件ev.events=EPOLLIN|EPOLLET;//ev.events=EPOLLIN;//注册evepoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);}else if(events[i].events&EPOLLIN){cout << "EPOLLIN" << endl;if( (sockfd = events[i].data.fd) < 0)continue;if( (n = read(sockfd, line, MAXLINE)) < 0) {if(errno == ECONNRESET) {close(sockfd);events[i].data.fd = -1;} elsestd::cout<<"readline error"<<std::endl;} else if(n == 0) {close(sockfd);events[i].data.fd = -1;}line[n] = '\0';cout << "read " << line << endl;//设置用于写操作的文件描述符ev.data.fd=sockfd;//设置用于注测的写操作事件ev.events=EPOLLOUT|EPOLLET;//修改sockfd上要处理的事件为EPOLLOUT//epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);}else if(events[i].events&EPOLLOUT){sockfd = events[i].data.fd;write(sockfd, line, n);//设置用于读操作的文件描述符ev.data.fd=sockfd;//设置用于注测的读操作事件ev.events=EPOLLIN|EPOLLET;//修改sockfd上要处理的事件为EPOLINepoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);}}}return 0;}下面给出测试所用的Perl写的client端,在client中发送10字节的数据,同时让client在发送完数据之后进入死循环, 也就是在发送完之后连接的状态不发生改变--既不再发送数据, 也不关闭连接,这样才能观察出server的状态: #!/usr/bin/perluse IO::Socket;my $host = "127.0.0.1";my $port = 5000;my $socket = IO::Socket::INET->new("$host:$port") or die "create socket error $@"; my $msg_out = "1234567890";print $socket $msg_out;print "now send over, go to sleep\n";while(1){sleep(1);}送了10字节的数据,也就是说,server仅当第一次监听到了EPOLLIN事件,由于没有读取完数据,而且采用的是ET模式,状态在此之后不发生变化,因此server 再也接收不到EPOLLIN事件了.(友情提示:上面的这个测试客户端,当你关闭它的时候会再次出发IO可读事件给server,此时server就会去读取剩下的5字节数据了,但是这一事件与前面描述的ET性质并不矛盾.)如果我们把client改为这样:#!/usr/bin/perluse IO::Socket;my $host = "127.0.0.1";my $port = 5000;my $socket = IO::Socket::INET->new("$host:$port") or die "create socket error $@"; my $msg_out = "1234567890";print $socket $msg_out;print "now send over, go to sleep\n";sleep(5);print "5 second gone send another line\n";print $socket $msg_out;while(1){sleep(1);}可以发现,在server接收完5字节的数据之后一直监听不到client的事件,而当client休眠5秒之后重新发送数据,server再次监听到了变化,只不过因为只是读取了5个字节,仍然有10个字节的数据(client第二次发送的数据)没有接收完.如果上面的实验中,对accept的socket都采用的是LT模式,那么只要还有数据留在buffer中,server就会继续得到通知,读者可以自行改动代码进行实验.基于这两个实验,可以得出这样的结论:ET模式仅当状态发生变化的时候才获得通知,这里所谓的状态的变化并不包括缓冲区中还有未处理的数据,也就是说,如果要采用ET模式,需要一直read/write直到出错为止,很多人反映为什么采用ET模式只接收了一局部数据就再也得不到通知了,大多因为这样;而LT模式是只要有数据没有处理就会一直通知下去的.补充说明一下这里一直强调的"状态变化"是什么:1)对于监听可读事件时,如果是socket是监听socket,那么当有新的主动连接到来为状态发生变化;对一般的socket而言,协议栈中相应的缓冲区有新的数据为状态发生变化.但是,如果在一个时间同时接收了N个连接(N>1),但是监听socket只accept了一个连接,那么其它未 accept的连接将不会在ET模式下给监听socket发出通知,此时状态不发生变化;对于一般的socket,就如例子中而言,如果对应的缓冲区本身已经有了N字节的数据,而只取出了小于N字节的数据,那么残存的数据不会造成状态发生变化.2)对于监听可写事件时,同理可推,不再详述.而不管是监听可读还是可写,对方关闭socket连接都将造成状态发生变化,比方在例子中,如果强行中断client脚本,也就是主动中断了socket连接,那么都将造成server端发生状态的变化,从而server得到通知,将已经在本方缓冲区中的数据读出.把前面的描述可以总结如下:仅当对方的动作(发出数据,关闭连接等)造成的事件才能导致状态发生变化,而本方协议栈中已经处理的事件(包括接收了对方的数据,接收了对方的主动连接请求)并不是造成状态发生变化的必要条件,状态变化一定是对方造成的.所以在ET模式下的,必须一直处理到出错或者完全处理完毕,才能进行下一个动作,否那么可能会发生错误.另外,从这个例子中,也可以阐述一些根本的网络编程概念.首先,连接的两端中,一端发送成功并不代表着对方上层应用程序接收成功, 就拿上面的client测试程序来说,10字节的数据已经发送成功,但是上层的server并没有调用read读取数据,因此发送成功仅仅说明了数据被对方的协议栈接收存放在了相应的buffer中,而上层的应用程序是否接收了这局部数据不得而知;同样的,读取数据时也只代表着本方协议栈的对应buffer中有数据可读,而此时时候在对端是否在发送数据也不得而知.epoll精髓在linux的网络编程中,很长的时间都在使用select来做事件触发。

rdd编程初级实践实验总结

rdd编程初级实践实验总结

rdd编程初级实践实验总结嘿,大家好!今天咱们聊聊rdd编程的初级实践,嘿,别急,虽然听上去像个高深的黑科技,其实就是个有趣的玩意儿。

说到rdd,真的是一个令人兴奋的词。

想象一下,你手里有一大堆数据,像是收集到的宝藏,想把它们整理得井井有条,嘿,这时候rdd 就像你最得力的助手,帮你把这些数据变得有条理。

就像做家务,越早清理,越能享受干净的环境,哈哈!刚开始接触rdd的时候,我心里想,哎呀,这可真是个头疼的玩意儿。

不过,真到了动手实践的时候,才发现其实并没有那么复杂。

rdd就是一个分布式数据集,听上去高大上,其实就是把数据分成很多小块,然后在不同的机器上处理,嘿,分散了风险,提升了效率。

就像朋友们聚会时,每个人负责做一道菜,结果大家的饭桌上就变得热闹非凡。

实践的时候,大家一定要注意,先得创建一个rdd,最简单的方法就是从一个集合中创建。

就像在家里开派对,先得把客人们召集齐,才能开始嗨嘛!用Spark的parallelize方法,就能轻松搞定。

创建完rdd,接下来就可以施展你的编程技能,进行各种操作。

像是过滤数据,像是把不合格的菜品挑出来,哈哈,是不是很形象?说到操作,我得提提map和filter。

这两个方法真是太实用了。

map就像是给每道菜加点调料,让它们更加美味。

你想把每个数据项都变成你想要的样子,直接用map就搞定。

而filter就像是在菜市场挑货,只留下新鲜的。

你想要那些符合条件的数据,就用filter,一下子把不合格的都给过滤掉,真是痛快!不过,rdd编程不只是简单的操作。

像是一个厨房,得有好工具才能做出美味的菜。

收集到的数据就像是食材,想要做出好菜,得学会合理搭配。

这时候的reduce操作就像是把所有的菜品都汇聚到一起,形成一顿丰盛的盛宴。

用reduce方法把数据聚合成一个结果,哇,成就感满满!还有一点,我特别想说的就是rdd的懒加载特性。

这可真是个神奇的设定,嘿!一开始你可能没觉得,但等到你真的执行行动的时候,rdd才会真正计算。

eventgroup概念

eventgroup概念

eventgroup概念什么是eventgroup?EventGroup是一个在事件驱动编程中常用的概念。

它是一种用于组织和管理事件的机制,可以将相关的事件分组,并对这些事件进行管理和处理。

EventGroup可以帮助开发人员更好地组织代码和处理复杂的事件流。

EventGroup的作用EventGroup的主要作用是将相关的事件分组,以便更好地管理和处理这些事件。

它可以帮助开发人员将复杂的事件流划分为多个小组,从而简化代码的逻辑和结构。

通过EventGroup,开发人员可以更好地组织和处理事件,提高代码的可读性和可维护性。

EventGroup的基本特性EventGroup具有以下基本特性:1.分组管理:EventGroup可以将相关的事件分组,以便更好地管理和处理这些事件。

每个EventGroup都有一个唯一的标识符,用于区分不同的分组。

2.事件注册:开发人员可以向EventGroup注册事件,告诉EventGroup需要监听和处理哪些事件。

当注册的事件触发时,EventGroup会调用相应的处理函数进行处理。

3.事件触发:事件可以通过外部触发或内部触发。

外部触发是指由外部代码显式地触发事件,而内部触发是指由EventGroup内部的其他事件触发。

4.事件处理:每个事件都有一个相应的处理函数,用于处理事件发生时的逻辑。

事件处理函数可以是同步的,也可以是异步的,具体取决于事件的要求和开发人员的设计。

5.事件传递:EventGroup可以将事件传递给其他EventGroup,以便实现不同分组之间的事件通信和协作。

这种事件传递通常是通过事件监听和事件触发来实现的。

EventGroup的应用场景EventGroup在事件驱动编程中有广泛的应用场景。

以下是一些常见的应用场景:1.UI事件处理:在图形界面开发中,经常需要处理各种用户交互事件,如点击、拖动、输入等。

通过EventGroup可以将这些事件分组,并按照一定的逻辑进行处理。

event用法

event用法

event用法Event(事件)是编程中常用的一个概念,用于描述计算机程序中发生的特定动作或状态变化。

在不同的编程语言和框架中,Event的使用方式有所不同,但基本的原理和用法是相似的。

在很多编程语言中,Event常常被用作一种触发机制,用于通知程序的其他部分发生了某种特定的动作或状态变化。

它可以在用户交互、文件读写、网络通信等各种场景下使用。

在使用Event时,通常有两个重要的概念:Event触发者和Event监听者。

Event触发者负责发起Event,而Event监听者则负责接收并处理Event。

Event的用法一般分为以下几个步骤:1.定义Event:首先,需要定义一个Event的类型或类。

这个类型或类用于描述Event的属性和行为。

2.注册Event监听者: 在代码中,需要注册一个或多个Event监听者。

这样当指定的Event被触发时,监听者将会收到通知。

3.触发Event:在适当的时机,通过触发Event的方式来通知程序中的其他部分,某个特定的动作或状态变化已经发生。

4.处理Event:Event监听者在收到Event通知后,会执行相应的处理逻辑。

这可以是调用一个函数、执行一段代码,或者触发其他的Event。

通过使用Event,我们可以将程序的各个部分解耦,提高代码的可读性和可维护性。

在复杂的程序中,Event可以帮助我们更好地组织代码、分离关注点、实现模块化开发。

不同的编程语言和框架提供了不同的Event处理机制,例如JavaScript中的事件监听器、C#中的事件委托、Java中的观察者模式等等。

因此,在具体的开发中,需要根据所使用的技术进行相应的Event处理方式。

总的来说,Event是一种常见的编程概念,用于描述程序中发生的特定动作或状态变化。

合理使用Event可以提高程序的灵活性和可扩展性,同时也让程序更易于维护和理解。

ee自学指南

ee自学指南

ee自学指南
1. 了解ee是什么
ee是一种程序设计范式,全称为"事件驱动编程"(Event-Driven Programming)。

它是一种编程模型,应用程序通过响应事件来决定其执行流程。

事件可以是用户的输入、系统中断或其他来自外部的通知。

2. 掌握ee的核心概念
- 事件(Event):触发应用程序响应的动作或状态变化。

- 事件源(Event Source):产生事件的对象或组件。

- 事件处理程序(Event Handler):负责响应事件的函数或方法。

- 事件循环(Event Loop):一个无限循环,持续监听和分派事件。

3. 学习使用ee的框架和库
不同编程语言都有支持ee编程的框架和库,比如JavaScript中的Node.js、Python中的Twisted等。

这些框架提供了事件循环实现、事件分派机制等功能。

4. 实践ee编程
最好的学习方式是动手编写一些ee程序,体会其编程模型。

可以从简单的GUI程序、网络服务器等入手,逐步实现更复杂的应用。

5. 理解ee的优缺点
ee编程具有良好的响应性和高并发处理能力,但代码结构可能会变得
复杂。

需要权衡利弊,针对不同场景选择合适的编程范式。

6. 持续学习和实践
ee是一个重要的编程理念,在现代应用开发中得到广泛应用。

要持续学习新框架、新特性,保持对ee编程的理解和实践。

通过以上步骤,你可以循序渐进地学习和掌握ee编程。

记得多动手实践,并结合具体的项目需求灵活运用所学知识。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Eventlet定义:eventlet是一个用来处理和网络相关的python网络库,而且可以通过协程来实现并发,在eventlet里,把“协程”叫做greenthread。

所谓并发,就是开启了多个greenthread,并且对这些greenthread进行管理,以实现非阻塞式的I/O。

Eventlet特性:A、非阻塞I/O模型B、协程(Coroutines)使得开发者可以采用阻塞式的开发风格,却能够实现非阻塞I/O的效果C、隐式事件调度,使得可以在Python解释器或者应用程序的某一部分去使用Eventlet关于协程,大致可以理解成允许子程序可以多次暂停和恢复执行,是实现多任务的一种有效手段,Eventlet的基础是greenlet,这是实现"协程(Coroutine)" 的基础。

协程又被称作"微线程“,简单点说就是在一个原生线程上通过"拷贝"和"切换" 堆栈帧数据来实现执行多个工作,看上去和传统的"单CPU,多线程(Threading)"执行方式差不多Eventlet的安装:Windows下安装1、从下载ActivePython的安装文件,安装ActivePython,在环境变量中添加python(CLASSPATH和PATH中都需要)2、在cmd中输入python,出现如下显示,表明安装python安装成功3、进入cmd下,输入"easy_install eventlet"命令就会从互联网上下载并自动安装eventlet到python目录中(目录示例:C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet)4、输入python,进入python环境,输入import eventlet命令,出现以下输出表明eventlet安装成功Linux下安装:wgettar -zxf ActivePython-2.7.2.5-linux-x86_64.tar.gzcd ActivePython-2.7.2.5-linux-x86_64make installeasy_install eventlet关于eventlet可以参照eventlet的官方网站:import eventletpool = eventlet.GreenPool(10000)while True:pool.spawn(func,args)说明:1、GreenPool 用来实现协程,保证并行2、pool = eventlet.GreenPool(10000) 创建一个可以处理10000 个客户端连接的线程池,应用场景:做一个IM 原型时,服务器需要处理多客户端连接但又不想使用传统的多线程编程。

3、spawn() 启动一个GreenThread 执行目标函数完成具体业务.4、每个func之间切换,实施“你运行一会、我运行一会”,并且在进行切换时必须指定何时切换以及切换到哪,当出现阻塞时,就显式切换到另一段没有被阻塞的代码段执行,直到原先的阻塞状况消失以后,再人工切换回原来的代码段继续处理.5、eventlet 可以用来处理多线程方面的工作,但它使用的是green threads 概念,所以用资源的开销很少。

Eventlet中常用类说明:greenthread1)sleep(seconds=0):中止当前的GreenThread,以允许其它的GreenThread 执行。

2)spawn(func,*args,**kwargs): 创建一个GreenThread 去运行func这个函数,*args,**kwargs是传递给func的参数。

返回值是一个eventlet .GreenThread对象,这个对象可以用来接受func函数运行的返回值。

3) spawn_n(func,*args,**kwargs):这个函数和spawn()有点类似,不同的是它没有返回值,因此效率更高。

4) spawn_after(seconds,func,*args,**kwargs):这个函数和spawn()基本上一样,都有一样的返回值,不同的是它可以限定在什么时候执行这个GreenThread,即在seconds秒之后,启动这个GreenThreadps:源码地址C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet\greenthrea d.pyGreenPool这是一个类,继承object,在这个类中用set集合来容纳所创建的GreenThread,并且可以指定容纳线程的最大数量(默认是1000个),它的内部是用Semaphore和Event这两个类来对池进行控制的,这样就构成了线程池。

其中,有几个比较重要的方法:running(self):返回当前池中正在执行函数的GreenThread数free(self):返回当前池中仍可容纳的GreenThread数spawn(self, function, *args, **kwargs):返回GreenThread ,可以接受func 函数执行后返回的结果spawn_n(self, function, *args, **kwargs):同spawn(self, function, *args, **kwargs),但是不返回结果starmap(self, function, iterable)和imap(self, function, *iterables):这两个函数和标准的库函数中的这两个函数实现的功能是一样的,所不同的是这里将这两个函数的执行放到了GreenThread中。

前者实现的是从iterable 中取出每一项作为function的参数来执行,后者则是分别从iterables中各取一项,作为function的参数去执行。

如:imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000ps:源码地址C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet\greenpool.p yGreenPile这也是一个类,继承object,在它内部维护了一个GreenPool对象和一个Queue 对象。

这个GreenPool对象可以是从外部传递进来的,也可以是在类内部创建的,GreenPool对象主要是用来创建GreenThread的,即在GreenPile内部调用了GreenPool.spawn()方法。

而Queue对象则是用来保存spawn()方法的返回值的,即Queue中保存的是GreenThread对象。

并且它还实现了next()方法,也就意味着GreenPile对象具有了迭代器的性质。

所以如果我们要对GreenThread的返回值进行操作的话,用这个类是再好不过的了。

ps:源码地址C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet\greenpool.p yQueue继承LightQueue,Queue中包含了两个方法:task_done()å’Œjoin()task_done()是被GreenThread所调用的,表示在这个项上的所有工作都做完了join()是阻塞,直到队列中所有的任务都完成。

LifoQueue和PriorityQueue都是Queue的子类,是存放数据的两种不同的方式。

LifoQueue检索的规则是最近加入的最先检索PriorityQueue检索的规则是优先级最低的最先检索ps:源码地址C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet\queue.pyNetwork Convenience Functions(和网络相关的函数)这些函数定义在convenience.py文件中,对和socket相关的网络通信进行了包装,注意,这里用的socket是经过修改后的socket,以使它使用绿GreenThread,主要有以下方法:1)connect(addr, family=socket.AF_INET, bind=None)主要执行了以下几个步骤:新建了一个TCP类型的socket,绑定本地的ip和端口,和远程的地址进行连接,源码如下:参数说明:addr:需要连接的服务器的地址,对于TCP sockets来说,addr是一个元组(host, port)Family:socket family,可选Bind:需要绑定的本地地址,可选2)listen(addr, family=socket.AF_INET, backlog=50)过程和connect()类似,只是把connect()换成了listen(),backlog指定了最大的连接数量,源码如下:参数说明:addr:监听的地址,对于TCP sockets来说,是一个元组(host, port)socket family,可选backlog:队列连接最大数,最小为13)serve(sock, handle, concurrency=1000)这个函数直接创建了一个socket服务器,在它内部创建了一个GreenPool对象,默认的最大GreenThread数是1000,然后是一个循环来接受连接,源码如下:ps:源码地址C:\Python27\Lib\site-packages\eventlet-0.9.17-py2.7.egg\eventlet\convenience.pyTPoolTPool的定义为Simple thread pool(简单的线程池),TPool中的线程大小默认为20,可以在引入TPool前通过配置环境变量EVENTLET_THREADPOOL_SIZE来更改线程池的大小。

TPool中主要方法定义为:execute(meth,*args, **kwargs)该方法的含义为:在一个python的线程中执行meth方法时,会锁住当前greenthread直到meth执行完成Example:Event很相似,但是Event只能保存一条结果,Event的send()方法Event跟QueueGreenPile示例。

相关文档
最新文档