本文目录一览: 1、select和epoll的区别 2、...
先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法
一、问题引出 联系区别
问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种:
1.使用多进程或者多线程,但是这种方法会造成程序的复杂,而且对与进程与线程的创建维护也需要很多的开销。(Apache服务器是用的子进程的方式,优点可以隔离用户)
2.用一个进程,但是使用非阻塞的I/O读取数据,当一个I/O不可读的时候立刻返回,检查下一个是否可读,这种形式的循环为轮询(polling),这种方法比较浪费CPU时间,因为大多数时间是不可读,但是仍花费时间不断反复执行read系统调用。
3.异步I/O(asynchronous I/O),当一个描述符准备好的时候用一个信号告诉进程,但是由于信号个数有限,多个描述符时不适用。
4.一种较好的方式为I/O多路转接(I/O multiplexing)(貌似也翻译多路复用),先构造一张有关描述符的列表(epoll中为队列),然后调用一个函数,直到这些描述符中的一个准备好时才返回,返回时告诉进程哪些I/O就绪。select和epoll这两个机制都是多路I/O机制的解决方案,select为POSIX标准中的,而epoll为Linux所特有的。
区别(epoll相对select优点)主要有三:
1.select的句柄数目受限,在linux/posix_types.h头文件有这样的声明:#define __FD_SETSIZE 1024 表示select最多同时监听1024个fd。而epoll没有,它的限制是最大的打开文件句柄数目。
2.epoll的最大好处是不会随着FD的数目增长而降低效率,在selec中采用轮询处理,其中的数据结构类似一个数组的数据结构,而epoll是维护一个队列,直接看队列是不是空就可以了。epoll只会对"活跃"的socket进行操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数(把这个句柄加入队列),其他idle状态句柄则不会,在这点上,epoll实现了一个"伪"AIO。但是如果绝大部分的I/O都是“活跃的”,每个I/O端口使用率很高的话,epoll效率不一定比select高(可能是要维护队列复杂)。
3.使用mmap加速内核与用户空间的消息传递。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
二、接口
1)select
1. int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr);
struct timeval{
long tv_sec;
long tv_usec;
}
有三种情况:tvptr == NULL 永远等待;tvptr-tv_sec == 0 tvptr-tv_usec == 0 完全不等待;不等于0的时候为等待的时间。select的三个指针都可以为空,这时候select提供了一种比sleep更精确的定时器。注意select的第一个参数maxfdp1并不是描述符的个数,而是最大的描述符加1,一是起限制作用,防止出错,二来可以给内核轮询的时候提供一个上届,提高效率。select返回-1表示出错,0表示超时,返回正值是所有的已经准备好的描述符个数(同一个描述符如果读和写都准备好,对结果影响是+2)。
2.int FD_ISSET(int fd, fd_set *fdset); fd在描述符集合中非0,否则返回0
3.int FD_CLR(int fd, fd_set *fd_set); int FD_SET(int fd, fd_set *fdset) ;int FD_ZERO(fd_set *fdset);
用一段linux 中man里的话“FD_ZERO() clears a set.FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set. FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns.”这几个函数与描述符的0和1没关系,只是添加删除检测描述符是否在set中。
2)epoll
1.int epoll_create(int size);
创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大。这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。
2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll的事件注册函数,它不同与select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。第一个参数是epoll_create()的返回值,第二个参数表示动作,用三个宏来表示:
EPOLL_CTL_ADD:注册新的fd到epfd中;
EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
EPOLL_CTL_DEL:从epfd中删除一个fd;
第三个参数是需要监听的fd,第四个参数是告诉内核需要监听什么事,struct epoll_event结构如下:
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
events可以是以下几个宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里
关于epoll工作模式ET,LT
LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.
ET (edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了,但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once)
3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)
等待事件的产生,类似于select()调用。参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1永久阻塞)。该函数返回需要处理的事件数目,如返回0表示已超时。
请采纳。
假的,有一家公司叫“厦门陆通国际旅行社”确实在美国的OTC市场挂牌交易,代码是LTGJ,但不存在LTLT这个代码。
而且通过查询这家公司的财务状况可以发现这家公司根本就没有经营活动,营业收入一直是0,只有负债没有资产
厦门陆通是靠非法集资过日子,公司场地租的,所有财料,全部作假,这样的诈骗集团能上市吗?
巴氏杀菌,即低温消毒,就是利用较低的温度(一般在60~82℃)在一定时间内,对食品进行加热处理,达到杀死微生物营养体的目的。既可杀死病菌又能保持物品中营养物质风味不变。
这是法国生物学家路易·巴斯德于1862年发明的消毒方法,主要用于牛奶上,杀灭牛奶里含有的病菌。
还可用于消毒啤酒、白酒等,经过巴氏消毒的啤酒叫熟啤,为普通啤酒;不经巴氏消毒,只能冻藏保鲜的啤酒就是生啤。
扩展资料
主要原理
巴氏杀菌是将混合原料加热至68~70℃,并保持此温度30分钟以后急速冷却到4-5℃,因为一般细菌的致死点均为温度68℃与时间30分钟以下。
所以,将混合原料经此法处理后,可杀灭其中的致病性细菌和绝大多数非致病性细菌。混合原料加热后突然冷却,急剧的热与冷变化也可以促使细菌的死亡。
在一定温度范围内,温度越低,细菌繁殖越慢;温度越高,繁殖越快(一般微生物生长的适宜温度为28℃-37℃),但温度太高,细菌就会死亡。不同的细菌有不同的最适生长温度和耐热、耐冷能力。
巴氏消毒其实就是利用病原体不是很耐热的特点,用适当的温度和保温时间处理,将其全部杀灭。但经巴氏消毒后,仍保留了小部分无害或有益、较耐热的细菌或细菌芽孢,因此巴氏消毒牛奶要在4℃左右的温度下保存,且只能保存3~10天,最多16天。
参考资料来源:百度百科--巴氏灭菌法
参考资料来源:百度百科--巴氏消毒
中的淀粉直链分部已经老化,这就是面包产生弹性和柔软结构的原因。随着放置时间的延长,面包中的支链淀粉分部的直链部分慢慢缔合,而使柔软的面包逐渐变硬,这种现象叫“变陈”。
“变陈”的速度与温度有关。在低温时(冷冻点以上)老化较快,而面包放冰箱中,变硬的程度来得更快。
2.黄瓜 青椒 不宜久存冰箱
黄瓜、青椒在冰箱中久存,会出现冻“伤”———变黑、变软、变味。黄瓜还会长毛发黏。因为冰箱里存放的温度一般为4℃至6℃左右,而黄瓜贮存适宜温度为10℃至12℃,青椒为7℃至8℃。故不宜久存。
3.香蕉
将香蕉放在12℃以下的地方贮存,会使香蕉发黑腐烂。
4.西红柿
西红柿经低温冷冻后,肉质呈水泡状,显得软烂,或出现散裂现象,表面有黑斑、煮不熟,无鲜味,严重的则酸败腐烂。
5.火腿
如将火腿放入冰箱低温贮存,其中的水分就会结冰,脂肪析出,腿肉结块或松散,肉质变味,极易腐败。
6.巧克力
巧克力在冰箱中冷存后,一旦取出,在室温条件下即会在其表面结出一层白霜,极易发霉变质,失去原味。
7.鲜荔枝
如将鲜荔枝在0℃的环境中放置一天,即会使之表皮变黑、果肉变味。
8.食品放冰箱能放多久列表
鲜蛋:冷藏30~60天
熟蛋:冷藏6~7天
牛奶:冷藏5~6天
酸奶:冷藏7~10天
鱼类:冷藏1~2天 冷冻90~180天
牛肉:冷藏1~2天 冷冻90天
肉排:冷藏2~3天,冷冻270天
香肠:冷藏9天, 冷冻60天
鸡肉:冷藏2~3天,冷冻360天
罐头食品:未开罐冷藏360天
花生酱、芝麻酱:已开罐冷藏90天
咖啡:已开罐冷藏14天
苹果:冷藏7~12天
柑桔:冷藏7天
梨:冷藏1~2天
熟西红柿:冷藏12天
菠菜:冷藏3~5天
胡萝卜、芹菜:冷藏7~14天
9.冰箱使用时的六大禁忌
a.热的食物绝对不能放入运转着的电冰箱内。
b.存放食物不宜过满、过紧,要留有空隙,以利冷空气对流,减轻机组负荷,延长使用寿命,节省电量。
c.食物不可生熟混放在一起,以保持卫生。按食物存放时间、温度要求,合理利用箱内空间,不要把食物直接放在蒸发器表面上,要放在器皿里,以免冻结在蒸发器上,不便取出。
d.鲜鱼、肉等食品不可以不作处理就放进冰箱。鲜鱼、肉要用塑料袋封装,在冷冻室贮藏。蔬菜、水果要把外表面水分擦干,放入箱内最下面,以零上温度贮藏为宜。
e.不能把瓶装液体饮料放进冷冻室内,以免冻裂包装瓶。应放在冷藏箱内或门档上,以4℃左右温度贮藏为最好。
f.存贮食物的电冰箱不宜同时储藏化学药品。
此外:
A.黄瓜与西红柿:黄瓜忌乙烯,而西红柿含有乙烯,两者放在一起会使黄瓜变质腐烂。
B.面包与饼干:饼干干燥,也无水分,而面包的水分较多,两者放在一起,饼干会变软而失去香脆,面包则会变硬难吃。
C.米与水果:米易发热,水果受热则容易蒸发水分而干枯,而米亦会吸收水分后发生霉变或生虫。
D.鲜蛋与生姜、洋葱:蛋壳上有许多小气孔,生姜、洋葱的强烈气味会钻入气孔内,加速鲜蛋的变质,时间稍长,蛋就会发臭。
上一篇:中铁工业股票最新消息(中铁工业)
下一篇:603611雪球(603611)
发表评论