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

网站建设与管理考题怎么让百度搜到自己的网站

网站建设与管理考题,怎么让百度搜到自己的网站,wordpress手机端网站,seo营销型网站推广前言 epoll的触发模式是个引发讨论非常多的话题#xff0c;网络上这方面总结的文章也很多#xff0c;首先从名字上就不是很统一#xff0c;LT模式常被称为水平触发、电平触发、条件触发#xff0c;而ET模式常被称为边缘触发、边沿触发等#xff0c;这些都是从英文翻译过来…前言 epoll的触发模式是个引发讨论非常多的话题网络上这方面总结的文章也很多首先从名字上就不是很统一LT模式常被称为水平触发、电平触发、条件触发而ET模式常被称为边缘触发、边沿触发等这些都是从英文翻译过来的只不过翻译的时候有些差异LT全称 level-triggeredET全称 edge-triggered。 虽然这个知识点热度很高但很多人对于它的理解总是差那么一点特别是在面试的时候很多面试者总是处于一种回忆和背诵的状态其实这两种模式真的不需要去死记硬背下面说说我个人对这两种模式的理解和记忆方法。 名称的记忆 每次提到ET边沿触发首先映入我脑海的是大学里《数字逻辑电路》这门课程里面会提到低电平、高电平当电平从低到高时会有一个上升沿而电平从高到低时会有一个下降沿这个“沿”就是边沿触发时提到的“边沿”跟马路边的马路牙子是同一种概念也就是指状态变化的时候。提起上升沿和下降沿我还是印象很深的当时我可是占用了好几节课的时间用Verilog语言写了一个显示“HELLO WORLD”的仿真波形依靠的就是电平变化中的“沿”。 状态变化 LT模式和ET模式可以类比电平变化来学习但是在实际应用中概念却不是完全一样的在epoll的应用中涉及到关于IO的读写而读写的状态变化有哪些呢可读、不可读、可写、不可写其实就是这四种状态而已以socket为例。 可读socket上有数据 不可读socket上没有数据了 可写socket上有空间可写 不可写socket上无空间可写 对于水平触发模式一个事件只要有就会一直触发。 对于边缘触发模式只有一个事件从无到有才会触发。LT模式 对于读事件 EPOLLIN只要socket上有未读完的数据EPOLLIN 就会一直触发对于写事件 EPOLLOUT只要socket可写一说指的是 TCP 窗口一直不饱和我觉得是TCP缓冲区未满时这一点还需验证EPOLLOUT 就会一直触发。 在这种模式下大家会认为读数据会简单一些因为即使数据没有读完那么下次调用epoll_wait()时它还会通知你在上没读完的文件描述符上继续读也就是人们常说的这种模式不用担心会丢失数据。 而写数据时因为使用 LT 模式会一直触发 EPOLLOUT 事件那么如果代码实现依赖于可写事件触发去发送数据一定要在数据发送完之后移除检测可写事件避免没有数据发送时无意义的触发。 ET模式 对于读事件 EPOLLIN只有socket上的数据从无到有EPOLLIN 才会触发对于写事件 EPOLLOUT只有在socket写缓冲区从不可写变为可写EPOLLOUT 才会触发刚刚添加事件完成调用epoll_wait时或者缓冲区从满到不满 这种模式听起来清爽了很多只有状态变化时才会通知通知的次数少了自然也会引发一些问题比如触发读事件后必须把数据收取干净因为你不一定有下一次机会再收取数据了即使不采用一次读取干净的方式也要把这个激活状态记下来后续接着处理否则如果数据残留到下一次消息来到时就会造成延迟现象。 这种模式下写事件触发后后续就不会再触发了如果还需要下一次的写事件触发来驱动发送数据就需要再次注册一次检测可写事件。 数据的读取和发送 关于数据的读比较好理解无论是LT模式还是ET模式监听到读事件从socket开始读数据就好了只不过读的逻辑有些差异LT模式下读事件触发后可以按需收取想要的字节数不用把本次接收到的数据收取干净ET模式下读事件触发后通常需要数据一次性收取干净。 而数据的写不太容易理解因为数据的读是对端发来数据导致的而数据的写其实是自己的逻辑层触发的所以在通过网络发数据时通常都不会去注册监可写事件一般都是调用 send 或者 write 函数直接发送如果发送过程中 函数返回 -1并且错误码是 EWOULDBLOCK 表明发送失败此时才会注册监听可写事件并将剩余的服务存入自定义的发送缓冲区中等可写事件触发后再接着将发送缓冲区中剩余的数据发送出去。 相关视频推荐 全网最详细epoll讲解6种epoll的设计让你吊打面试官 epoll实战揭秘-支撑亿级IO的底层基石 epoll的具体实现与epoll线程安全互斥锁、自旋锁、原子操作、CAS 免费学习地址c/c linux服务器开发/后台架构师 需要C/C Linux服务器架构师学习资料加qun812855908获取资料包括C/CLinuxgolang技术NginxZeroMQMySQLRedisfastdfsMongoDBZK流媒体CDNP2PK8SDockerTCP/IP协程DPDKffmpeg等免费分享 代码实践 基础代码 以下为一个epoll触发模式测试的基础代码也不算太长直接拿来就可以测试 #include sys/socket.h //for socket #include arpa/inet.h //for htonl htons #include sys/epoll.h //for epoll_ctl #include unistd.h //for close #include fcntl.h //for fcntl #include errno.h //for errno #include iostream //for coutclass fd_object { public:fd_object(int fd) { listen_fd fd; }~fd_object() { close(listen_fd); } private:int listen_fd; };/* ./epoll for lt mode and ./epoll 1 for et mode */ int main(int argc, char* argv[]) {//create a socket fdint listen_fd socket(AF_INET, SOCK_STREAM, 0);if (listen_fd -1){std::cout create listen socket fd error. std::endl;return -1;}fd_object obj(listen_fd);//set socket to non-blockint socket_flag fcntl(listen_fd, F_GETFL, 0);socket_flag | O_NONBLOCK;if (fcntl(listen_fd, F_SETFL, socket_flag) -1){std::cout set listen fd to nonblock error. std::endl;return -1;}//init server bind infoint port 51741;struct sockaddr_in bind_addr;bind_addr.sin_family AF_INET;bind_addr.sin_addr.s_addr htonl(INADDR_ANY);bind_addr.sin_port htons(port);if (bind(listen_fd, (struct sockaddr *)bind_addr, sizeof(bind_addr)) -1){std::cout bind listen socket fd error. std::endl;return -1;}//start listenif (listen(listen_fd, SOMAXCONN) -1){std::cout listen error. std::endl;return -1;}elsestd::cout start server at port [ port ] with [ (argc 1 ? LT : ET) ] mode. std::endl;//create a epoll fdint epoll_fd epoll_create(88);if (epoll_fd -1){std::cout create a epoll fd error. std::endl;return -1;}epoll_event listen_fd_event;listen_fd_event.data.fd listen_fd;listen_fd_event.events EPOLLIN;if (argc 1) listen_fd_event.events | EPOLLET;//add epoll event for listen fdif (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, listen_fd_event) -1){std::cout epoll ctl error. std::endl;return -1;}while (true){epoll_event epoll_events[1024];int n epoll_wait(epoll_fd, epoll_events, 1024, 1000);if (n 0)break;else if (n 0) //timeoutcontinue;for (int i 0; i n; i){if (epoll_events[i].events EPOLLIN)//trigger read event{if (epoll_events[i].data.fd listen_fd){//accept a new connectionstruct sockaddr_in client_addr;socklen_t client_addr_len sizeof(client_addr);int client_fd accept(listen_fd, (struct sockaddr*)client_addr, client_addr_len);if (client_fd -1)continue;socket_flag fcntl(client_fd, F_GETFL, 0);socket_flag | O_NONBLOCK;if (fcntl(client_fd, F_SETFL, socket_flag) -1){close(client_fd);std::cout set client fd to non-block error. std::endl;continue;}epoll_event client_fd_event;client_fd_event.data.fd client_fd;client_fd_event.events EPOLLIN | EPOLLOUT;if (argc 1) client_fd_event.events | EPOLLET;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, client_fd_event) -1){std::cout add client fd to epoll fd error. std::endl;close(client_fd);continue;}std::cout accept a new client fd [ client_fd ]. std::endl;}else{std::cout EPOLLIN event triggered for client fd [ epoll_events[i].data.fd ]. std::endl;char recvbuf[1024] { 0 };int m recv(epoll_events[i].data.fd, recvbuf, 1, 0); // only read 1 bytes when read event triggeredif (m 0 || (m 0 errno ! EWOULDBLOCK errno ! EINTR)){if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) ! -1)std::cout the client fd [ epoll_events[i].data.fd ] disconnected. std::endl;close(epoll_events[i].data.fd);}std::cout recv data from client fd [ epoll_events[i].data.fd ] and data is [ recvbuf ]. std::endl;}}else if (epoll_events[i].events EPOLLOUT){if (epoll_events[i].data.fd listen_fd) //trigger write eventcontinue;std::cout EPOLLOUT event triggered for client fd [ epoll_events[i].data.fd ]. std::endl;}}}return 0; } 简单说下这段代码的测试方法可以使用 g testepoll.cpp -o epoll 进行编译编译后通过 ./epoll 运行为LT模式通过 ./epoll et模式运行为ET模式我们用编译好的epoll程序作为服务器使用nc命令来模拟一个客户端。 测试分类 1.编译后直接./epoll然后在另一个命令行窗口用 nc -v 127.0.0.1 51741 命令模拟一次连接此时 ./epoll 会产生大量的 EPOLLOUT event triggered for client fd ...那是因为在LT模式下EPOLLOUT会被一直触发。 alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll start server at port [51741] with [LT] mode. accept a new client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLOUT event triggered for client fd [5]. ... 2.注释包含 EPOLLOUT event triggered for client fd 输出内容的第152行代码编译后 ./epoll运行然后在另一个命令行窗口用 nc -v 127.0.0.1 51741 模拟一次连接后输入abcd回车可以看到服务器./epoll输出内容EPOLLIN被触发多次每次读取一个字节。 alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll start server at port [51741] with [LT] mode. accept a new client fd [5]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [a]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [b]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [c]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [d]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. 3.还原刚才注释的那行代码编译后执行 ./epoll et 启动服务器然后在另一个命令行窗口用 nc -v 127.0.0.1 51741 模拟一次连接后然后在另一个命令行窗口用 nc -v 127.0.0.1 51741 模拟一次连接服务器窗口显示触发了EPOLLOUT事件 alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll et start server at port [51741] with [ET] mode. accept a new client fd [5]. EPOLLOUT event triggered for client fd [5]. 在此基础上从刚刚运行nc命令的窗口中输入回车、输入回车、输出回车那么epoll服务器窗口看到的是触发了三次EPOLLIN事件每次收到一个回车: alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll et start server at port [51741] with [ET] mode. accept a new client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. 但是如果在nc模拟的客户端里输出abcd回车那么在epoll服务器窗口触发一次EPOLLIN事件接收到一个a之后便再也不会触发EPOLLIN了即使你在nc客户端在此输入也没有用那是因为在接受的缓冲区中一直还有数据新数据来时没有出现缓冲区从空到有数据的情况所以在ET模式下也注意这种情况。 alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll et start server at port [51741] with [ET] mode. accept a new client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [a]. 怎么解决ET触发了一次就不再触发了 改代码呗ET模式在连接后触发一次EPOLLOUT接收到数据时触发一次EPOLLIN如果数据没收完以后这两个事件就再也不会被触发了要想改变这种情况可以再次注册一下这两个事件时机可以选择接收到数据的时候所以可以修改这部分代码 else {std::cout EPOLLIN event triggered for client fd [ epoll_events[i].data.fd ]. std::endl;char recvbuf[1024] { 0 };int m recv(epoll_events[i].data.fd, recvbuf, 1, 0); // only read 1 bytes when read event triggeredif (m 0 || (m 0 errno ! EWOULDBLOCK errno ! EINTR)){if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) ! -1)std::cout the client fd [ epoll_events[i].data.fd ] disconnected. std::endl;close(epoll_events[i].data.fd);}std::cout recv data from client fd [ epoll_events[i].data.fd ] and data is [ recvbuf ]. std::endl; } 添加再次注册的逻辑 else {std::cout EPOLLIN event triggered for client fd [ epoll_events[i].data.fd ]. std::endl;char recvbuf[1024] { 0 };int m recv(epoll_events[i].data.fd, recvbuf, 1, 0); // only read 1 bytes when read event triggeredif (m 0 || (m 0 errno ! EWOULDBLOCK errno ! EINTR)){if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) ! -1)std::cout the client fd [ epoll_events[i].data.fd ] disconnected. std::endl;close(epoll_events[i].data.fd);}epoll_event client_fd_event;client_fd_event.data.fd epoll_events[i].data.fd;client_fd_event.events EPOLLIN | EPOLLOUT;if (argc 1) client_fd_event.events | EPOLLET;epoll_ctl(epoll_fd, EPOLL_CTL_MOD, epoll_events[i].data.fd, client_fd_event);std::cout recv data from client fd [ epoll_events[i].data.fd ] and data is [ recvbuf ]. std::endl; } 这次以./epoll et方式启动服务器使用nc -v 127.0.0.1 51741模拟客户端输入abc回车发现epoll服务器输出显示触发的事件变了 alberthome-pc:/mnt/d/data/cpp/testepoll$ ./epoll et start server at port [51741] with [ET] mode. accept a new client fd [5]. EPOLLOUT event triggered for client fd [5]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [a]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [b]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [c]. EPOLLIN event triggered for client fd [5]. recv data from client fd [5] and data is [ ]. EPOLLOUT event triggered for client fd [5]. 总结 LT模式会一直触发EPOLLOUT当缓冲区有数据时会一直触发EPOLLINET模式会在连接建立后触发一次EPOLLOUT当收到数据时会触发一次EPOLLINLT模式触发EPOLLIN时可以按需读取数据残留了数据还会再次通知读取ET模式触发EPOLLIN时必须把数据读取完否则即使来了新的数据也不会再次通知了LT模式的EPOLLOUT会一直触发所以发送完数据记得删除否则会产生大量不必要的通知ET模式的EPOLLOUT事件若数据未发送完需再次注册否则不会再有发送的机会通常发送网络数据时不会依赖EPOLLOUT事件只有在缓冲区满发送失败时会注册这个事件期待被通知后再次发送
http://www.sczhlp.com/news/169074/

相关文章:

  • 上海市交通建设工程安全质量监督站网站旅游网站建设方案预算
  • 廊坊建设公司网站网站审核备案表
  • 潍坊做外贸网站企业信息查询官网系统
  • 外贸网站用什么字体wordpress 连接qq视频
  • 网站建设模板犀牛云win8怎么建设网站
  • 网站建设设计简介专业的营销型网站培训中心
  • 响应式网站建设报价单中国企业500强门槛
  • 提供购物网站建设做app和做网站的区别
  • dw网站建设大型seo公司
  • 网站建设走的路线风格wordpress可以做大吗
  • 做电脑网站福州专业建站
  • 域名解析网站德州汇泽网站建设
  • 企业官方网站怎么申请网站 ftp
  • 网站域名实名认证官网插画设计网站推荐
  • 广东网广东网站建设站外调用WordPress评论
  • 如何制作多网页网站我想网上做网站
  • 网站营销活动页面制作大学生项目app策划书
  • 做网站需要哪些资料wordpress建站手机端
  • RabbitMQ 离线安装
  • Nginx 离线安装
  • docker 离线安装
  • uniapp 转回tabbar页面
  • 护栏板官方网站建设在线登录qq邮箱网页版官网
  • 电子商务网站建设与管理pdf下载湛江手机网站制作
  • 用ps做糖果店网站模板wordpress视频插件w
  • 2015年做哪些网站致富郑州交通建设投资有限公司网站
  • 广州市建设局网站银川做网站的公司
  • 哪里查网站备案信息扬中做网站的公司
  • 网站的建设初步定位qq查冻结网站怎么做
  • 凯里网站建设gzklyyasp个人网站论文