当前位置: 首页 > wzjs >正文

简述网站开发流程 旅游seo优化网站排名

简述网站开发流程 旅游,seo优化网站排名,装修三维效果图软件,seo整站优化报价一:背景 1. 讲故事 在windows平台上,相信很多人都知道.NET异步机制是借助了Windows自带的 IO完成端口 实现的异步交互,那在 Linux 下.NET 又是怎么玩的呢?主要还是传统的 select,poll,epoll 的IO多路复用…

一:背景

1. 讲故事

在windows平台上,相信很多人都知道.NET异步机制是借助了Windows自带的 IO完成端口 实现的异步交互,那在 Linux 下.NET 又是怎么玩的呢?主要还是传统的 select,poll,epoll 的IO多路复用,在 coreclr源代码中我们都能找到它们的影子。

  1. select & poll

在平台适配层的 pal.cpp 文件中,有这样的一句话。


#if HAVE_POLL
#include <poll.h>
#else
#include "pal/fakepoll.h"
#endif  // HAVE_POLL

简而言之就是在不支持 poll 的linux版本中使用 select(fakepoll) 模拟,参考代码如下:

  1. epoll

同样的在 linux 中你也会发现很多,截图如下:

二:select IO多路复用

1. select 解读

在没有 select 之前,我们需要手工管理多句柄的收发,在使用select IO多路复用技术之后,这些多句柄管理就由用户转交给linux系统了,这个也可以从核心的 select 函数看出。


int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  1. readfds,writefds,exceptfds

这三个字段依次监视着哪些句柄已成可读状态,哪些句柄已成可写状态,哪些句柄已成异常状态,那技术上是如何实现的呢?在libc 中定义了一个 bit 数组,刚好文件句柄fd值作为 bit数组的索引,linux 在内核中只需要扫描 __fds_bits 中哪些位为1 即可找到需要监控的句柄。


/* fd_set for select and pselect.  */
typedef struct{/* XPG4.2 requires this member name.  Otherwise avoid the namefrom the global namespace.  */
#ifdef __USE_XOPEN__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif} fd_set;
  1. nfds,timeout

为了减少扫描范围,提高程序性能,需要用户指定一个最大的扫描值到 nfds 上。后面的timeout即超时时间。

2. select 的一个小例子

说了再多还不如一个例子有说服力,我们使用 select 机制对 Console 控制台句柄 (STDIN_FILENO) 进行监控,一旦有数据进来立马输出,参考代码如下:


#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>int main()
{fd_set readfds;struct timeval timeout;char buf[256];printf("Enter text (press Ctrl+D to end):\n");while (1){FD_ZERO(&readfds);FD_SET(STDIN_FILENO, &readfds);timeout.tv_sec = 5; // 5秒超时timeout.tv_usec = 0;int ready = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &timeout);if (ready == -1){perror("select");break;}else if (ready == 0){printf("\nTimeout (5秒无输入).\n");break;}else if (FD_ISSET(STDIN_FILENO, &readfds)){// 使用 fgets 逐行读取if (fgets(buf, sizeof(buf), stdin) != NULL){printf("You entered: %s", buf); // 输出整行(包含换行符)}else{printf("\nEnd of input (Ctrl+D pressed).\n");break;}}}return 0;
}

稍微解释下代码逻辑。


/* Standard file descriptors.  */
#define	STDIN_FILENO	0	/* Standard input.  */
#define	STDOUT_FILENO	1	/* Standard output.  */
#define	STDERR_FILENO	2	/* Standard error output.  */
  1. 将 STDIN_FILENO=0 塞入到可读句柄监控 (readfds) 中。
  2. 数据进来之后 select 被唤醒,执行后续逻辑。
  3. 通过 FD_ISSET 判断 bit=0 的位置(STDIN_FILENO)是否可用,可用的话读取数据。

如果大家对 select 底层代码感兴趣,可以看下 linux 的 do_select 简化实现,大量的遍历逻辑(bit)。


static noinline_for_stack int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
{for (;;) {unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;bool can_busy_loop = false;inp = fds->in; outp = fds->out; exp = fds->ex;rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex;for (i = 0; i < n; ++rinp, ++routp, ++rexp) {in = *inp++; out = *outp++; ex = *exp++;all_bits = in | out | ex;for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) {mask = select_poll_one(i, wait, in, out, bit,busy_flag);if ((mask & POLLIN_SET) && (in & bit)) {res_in |= bit;retval++;wait->_qproc = NULL;}if ((mask & POLLOUT_SET) && (out & bit)) {res_out |= bit;retval++;wait->_qproc = NULL;}if ((mask & POLLEX_SET) && (ex & bit)) {res_ex |= bit;retval++;wait->_qproc = NULL;}}}if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, to, slack))timed_out = 1;}return retval;
}

三:epoll IO多路复用

1. epoll 解读

现在主流的软件(Redis,Nigix) 都是采用 epoll,它解决了select低效的遍历,毕竟数组最多支持1024个bit位,一旦句柄过多会影响异步读取的效率。epoll的底层借助了。

  1. 红黑树:对句柄进行管理,复杂度为 O(logN)。
  2. 就绪队列:一旦句柄变得可读或可写,内核会直接将句柄送到就绪队列。

libc中使用 epoll_wait 函数监视着就绪队列,一旦有数据立即提取,复杂度 O(1),其实这个机制和 Windows 的IO完成端口 已经很靠近了,最后配一下参考代码。


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>#define MAX_EVENTS 10   // 最大监听事件数
#define TIMEOUT_MS 5000 // epoll_wait 超时时间(毫秒)int main()
{int epoll_fd, nfds;                        // epoll 文件描述符和返回的事件数struct epoll_event ev, events[MAX_EVENTS]; // epoll 事件结构体char buf[256];// 创建 epoll 实例epoll_fd = epoll_create1(0);if (epoll_fd == -1){perror("epoll_create1");exit(EXIT_FAILURE);}// 配置并添加标准输入到 epoll 监听ev.events = EPOLLIN;       // 监听文件描述符的可读事件(输入)ev.data.fd = STDIN_FILENO; // 监听标准输入(文件描述符 0)if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1){perror("epoll_ctl: STDIN_FILENO");exit(EXIT_FAILURE);}printf("Enter text line by line (press Ctrl+D to end):\n");// 主循环:监听事件while (1){// 等待事件发生或超时nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, TIMEOUT_MS);if (nfds == -1){perror("epoll_wait");break;}else if (nfds == 0){printf("\nTimeout (5秒无输入).\n");break;}// 处理所有触发的事件for (int n = 0; n < nfds; ++n){if (events[n].data.fd == STDIN_FILENO){// 使用 fgets 逐行读取输入if (fgets(buf, sizeof(buf), stdin) != NULL){printf("You entered: %s", buf);}else{// 输入结束(用户按下 Ctrl+D)printf("\nEnd of input (Ctrl+D pressed).\n");break;}}}}close(epoll_fd);return 0;
}

四:总结

说了这么多,文尾总结下目前主流的 epoll 和 iocp 各自的特点。

特性epoll (Linux)IOCP (Windows)
模型事件驱动 (Reactor)完成端口 (Proactor)
核心思想通知可读写事件通知I/O操作完成
适用场景高并发网络编程高并发I/O操作
编程复杂度较低较高
网络I/O性能极佳(百万级连接)优秀
磁盘I/O支持有限完善
CPU利用率
内存开销
http://www.dtcms.com/wzjs/571180.html

相关文章:

  • 网站搭建网站管理潍坊高新建设局网站
  • 江门市专业做网站公司机械设计网
  • 网站页脚信息预约网站模板
  • 上海做网站公司推荐广西建设厅网站绿色建筑标识
  • 山东饰品行业网站制作网站制作设计哪家公司好
  • 个人网站模板html小程序建站平台
  • 网站建设重庆最加科技怎么给网站做开场动画
  • 不用花生壳做网站服务器wordpress建的网站
  • 如何与别的网站做友情链接服务网站欣赏
  • 足球网站模板下载wordpress下载页插件
  • 找做外墙油漆网站什么网站做跨境电子商务
  • 软件跟网站开发的区别公众号官网登录
  • 怎么做公司免费网站织梦网站文章发布模板下载
  • 太仓做企业网站服务器租赁合同范本
  • 网站开发工作商城网站定制建设价位
  • 南京建设网站维护2021深圳装修公司排名前十强
  • 网站建设备案优化网上书店网站建设方案策划
  • 非洲用什么网站做采购能够做冶金工程毕业设计的网站
  • 用html做网站的心得体会免费个人网站源码
  • 抖音网络营销案例抖音seo搜索引擎优化
  • 响应式网站开发遇到的问题导购网站怎么做
  • 网站开发公司+重庆网站建设成交话术
  • 凡科建站登录中山市路桥建设有限公司网站
  • 临沂专业网站制作北京网站优化经理
  • 重庆整站优化的电话销售wordpress云端采集
  • 帝国程序如何改网站标题asp.net做简易网站
  • 公司网站建设高端网站建设网页设计备案价格网站
  • 公司做个网站多少钱阿里云公司网站制作
  • 刘金鹏做网站网页设计产品介绍页面的制作
  • 桐乡建设规划局网站wordpress如何套用模板