【计算机网络】高级IO之select
文章目录
- 1. 什么是IO?
- 什么是高效 IO?
- 2. IO的五种模型
- 五种IO模型的概念理解
- 同步IO与异步IO
- 整体理解
- 3. 阻塞IO
- 4. 非阻塞IO
- setnonblock函数
- 为什么非阻塞IO会读取错误?
- 对错误码的进一步判断
- 检测数据没有就绪时,返回做一些其他事情
- 完整代码
- mytest.cc
- makefile
- 5. select
- 为什么要有select?
- select 接口
- 第一个参数 nfds的理解
- 什么是 输入 输出型参数
- 最后一个参数 timeout 的理解
- readfds writefds exceptfds 参数的理解
- select的返回值
1. 什么是IO?
IO:表示 输入 输出
当对方把连接建立好,但是不发数据
而我是一个线程,正在调用 read 来读,就会阻塞,一直等数据发送过来
即读取条件不满足的情况下,read或recv 只会等待
无论是有数据时的拷贝 ,还是没有数据时的等待
两者的时间成本,全都算到了用户头上
在用户的角度,IO= 等+数据拷贝
什么是高效 IO?
单位时间内, 等的比重越低, IO效率越高
当IO条件满足时,称为 IO事件就绪
2. IO的五种模型
五种IO模型的概念理解
如:钓鱼假设分为两步 , 钓鱼 = 等 + 钓
在鱼竿的钩子上挂一个鱼漂,浮在水面上,用来恒定鱼竿下水的深度
当鱼漂上下摆动时,就可以知道当前有鱼上钩了
1. 张三一般喜欢专注于一件事, 所以当张三钓鱼等待时,就会一直盯着鱼漂看 是否有鱼上钩
过了一段时间,鱼漂动了,张三拉动鱼竿,将鱼钓上来了,放入桶中
继续刚才钓鱼的动作
张三在钓鱼的过程中,只盯着鱼漂看,不干其他事情
2. 李四天生好动, 所以当李四钓鱼时,就不怎么看鱼漂,会左顾右看的张望
当发现鱼咬钩后,就把鱼钓上来,放入桶中
继续刚才钓鱼的动作
李四在钓鱼的过程中,除了看鱼漂,还做其他事情
3. 王五比较特别, 当王五钓鱼时,在鱼竿的顶部放上一个铃铛,等待鱼上钩
等待过程中,王五做着自己的事情
当王五听到铃铛响了时,就拉动鱼竿,将鱼钓上来了,放入桶中
继续刚才钓鱼的动作
王五在钓鱼的过程中,不看鱼漂,只听铃铛来判断是否有鱼上钩
4. 赵六是周围的首富,开皮卡来钓鱼,皮卡上装了10根鱼竿 (首富是来体验生活的)
使用10根鱼竿一起钓鱼,赵六就从前往后 依次查看 是否有鱼漂在动
5. 田七是方圆500公里的首富 (田七比赵六有钱)
田七很忙,每天都有各种会议要开,而且田七并不是想钓鱼,而是喜欢吃鱼
所以就 让司机小王帮忙去钓鱼
当鱼桶满了后,给田七打电话,就会来人把鱼带走
小王在钓鱼时,田七也正在开会
张三和李四钓是一样的,差别在等待鱼上钩的方式不同
张三为 鱼漂不动,他不动
李四为 鱼漂不动,会立马返回去做其他事情
张三的钓鱼方式 称为 阻塞IO
(数据没有就绪,调用的read接口不会返回)
李四的钓鱼方式 称为 非阻塞IO
(检测一次若没有数据,则会立马返回,过一段时间可以再次检测)
王五在鱼还没有钓上来之前,就知道当铃铛响了,就应该拉动鱼竿
王五的钓鱼方式 称为 信号驱动IO
赵六一次管理多个鱼竿,赵六的钓鱼方式称为 多路复用或多路转接
在这几个人中,赵六的钓鱼效率比较高
因为赵六的鱼竿比较多,所以鱼上钩的概率大 即等待时间比较短
所以赵六的钓鱼效率比较高
同步IO与异步IO
前四个人都要钓鱼的过程,所以都称为 同步IO
田七没有参与钓鱼的过程,没有等 ,也没有钓,只是 发起钓鱼的过程
田七的钓鱼方式 称为 异步IO
整体理解
钓 可以看作 数据拷贝
张三 李四 等人 可以看作 进程
田七可以看作是一个进程,司机小王可以看作是操作系统
鱼竿可以看作 文件描述符
鱼 可以看作是 数据
鱼咬钩 或 鱼漂动 、铃铛响 可以看作 IO事件就绪
一个进程 在文件描述符上读取数据时,若数据没有就绪,当前进程只能挂起等待
直到有IO时间就绪,数据才可以拷贝到对应的上层
3. 阻塞IO
阻塞IO:数据没有就绪,调用的read接口不会返回
通过使用 read 函数 从键盘中读,当代码写好时,若什么也不输入,则什么也不显示 则为阻塞IO
输入 man 2 read
从一个文件描述符 中 去读count个数据 到 buf缓冲区中
若获取成功,则返回 字节数据
若获取 为0,则表示读到文件结尾
若获取为-1,则表示失败,并设置错误码
0表示标准输入流
从标准输入流中 读buffer数组大小的数据 发送到 buffer中
运行可执行程序后,一直不输入,则导致read在等待,直到有数据输入才进行数据拷贝
4. 非阻塞IO
非阻塞IO:检测一次若没有数据,则会立马返回 做其他事情,过一段时间可以再次检测
通过使用 read 函数 从键盘中读,当代码写好时,就是不输入
通过这样的方式,模拟读取条件不满足的情况下,read只会等待的情况
在上述阻塞IO的代码的基础上 进行修改
setnonblock函数
输入 man fcntl
第一个参数为 文件描述符
第二个参数 表示 你要对文件描述符干什么
获得/设置文件状态标记(cmd=F_GETFL或F_SETFL)
通过设置文件状态标记,就可以将一个文件描述符 变为 非阻塞
使用 F_GETFL,将当前文件描述符的属性取出来
使用 F_SETFL,将文件描述符 状态进行设置,并加上一个 O_NONBLOCK (非阻塞) 参数
若函数返回 -1,则表示失败
创建一个函数 setnonblock,将文件描述符设置为非阻塞状态
先使用F_GETFL,获取对应文件描述符的属性
若获取失败,则返回错误原因和错误码
若获取成功,则使用 F_SETFL 将文件描述符状态设为非阻塞状态
为什么非阻塞IO会读取错误?
在主函数main中,将标准输入流改为非阻塞状态
并根据read的三种返回值,分别设置 返回提示 : 读取成功、文件结尾 和 读取错误
当将标准输入流设置为非阻塞状态后
再次运行可执行程序,直接就会读取失败
在调用read时,发现数据没有就绪 (当前读取检测速度太快,还没有输入,就报错了)
所以一旦底层数据没有就绪,就以出错的形式返回,但是不算真正的出错
但这样就没办法区分是真正出错还是 底层没有数据了
所以就通过出错码 进行进一步判断
对错误码的进一步判断
EAGAIN 和 EWOULDBLOCK 都是系统设置的,错误码都是11
用于判断没出错,但是以出错的形式返回 的错误码
若为真,则下次继续检测即可
若IO被信号中断,则重新检测
检测数据没有就绪时,返回做一些其他事情
非阻塞IO,是可以做到 当检测数据没有就绪 时,就返回做一些其他事情
定义一个 包装器 其参数为void 返回值为void ,并将其重命名为 func_t 类型
定义一个vetcor数组 ,其类型为 func_t
设置三个任务,分别为PrintLog OperMysql CheckNet
在创建LoadTask函数,将任务分别插入到funcs数组中
在主函数main中,调用 LoadTask函数 以此加载任务
创建一个 HandlerALLTask函数,用于遍历 vector数组 ,数组元素为任务
当数据没有就绪时,就返回 处理任务
完整代码
mytest.cc
#include<iostream>
#include<unistd.h>
#include<fcntl.h>
#include<cstdio>
#include<cstring>
#include<vector>
#include<functional>
using namespace std;//任务
void PrintLog()//打印日志
{cout<<"这是一个打印日志例程"<<endl;
}void OperMysql()
{cout<<"这是一个操作数据库的例程"<<endl;
}void CheckNet()
{cout<<"这是一个检测网络状态的例程"<<endl;
}using func_t =function<void(void)>;
vector<func_t> funcs;void LoadTask()
{funcs.push_back(PrintLog);funcs.push_back( OperMysql);funcs.push_back(CheckNet);
}void HandlerALLTask()
{//遍历vector数组for(auto& func:funcs){func();}
}void SetNonBlock(int fd)//将文件描述符设为非阻塞
{int fl=fcntl(fd,F_GETFL);//获取当前文件描述符的指定状态标志位if(fl<0)//获取失败{cerr<<"error string: "<<strerror(errno)<<"error code: "<<errno<<endl;}fcntl(fd,F_SETFL,fl | O_NONBLOCK);//将文件描述符状态设为非阻塞状态
}int main()
{char buffer[64];SetNonBlock(0);//将标准输入流 改为非阻塞状态LoadTask();//加载任务while(true){//0表示标准输入流ssize_t n=read(0,buffer,sizeof(buffer)-1);//检测条件是否就绪if(n>0)//读取成功{buffer[n-1]=0; cout<<"echo# "<<buffer<<endl; }else if(n==0)//读到文件结尾{cout<<"end file"<<endl;}else//读取失败 {if(errno==EAGAIN || errno ==EWOULDBLOCK){//若为真,说明没出错,只是以出错返回//底层数据没有准备好,下次继续检测HandlerALLTask();//遍历数组 处理任务sleep(1);cout<<"data not ready"<<endl;continue;}else if(errno == EINTR){//IO被信号中断,需要重新检测continue;}else //真正的错误{cout<<"read error"<<"error string: "<<strerror(errno)<<"error code: "<<errno<<endl;break;}}sleep(1);}return 0;
}
makefile
mytest:mytest.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f mytest
5. select
为什么要有select?
read/recv 等 文件接口只有一个文件描述符
想要 让一个接口等待多个文件描述符,而read等接口是不具备这个能力的
操作系统就设计一个接口 select,用于多路复用
select 作用
1.等待多个文件描述符
2.只负责等(没有数据拷贝的能力)
select 接口
输入 man select
由于select只负责等待,不负责拷贝,所以没有缓冲区
第一个参数 nfds的理解
第一个参数 nfds,是一个输入型参数 ,表示 select等待的多个文件描述符(fd)数字层面 最大的+1
(文件描述符的本质为 数组下标,多个文件描述符中 数值最大的文件描述符值+1 即nfds )
什么是 输入 输出型参数
用户把数据交给操作系统,同样操作系统也要 通过这些输出型参数 把结果 交给用户
为了让 用户 和 操作系统之间进行信息传递,就把参数设置为 输入 输出型参数
最后一个参数 timeout 的理解
timeout 是一个 输入 输出型参数
timeout的数据类型 为struct timeval
可以一个时间结构体,tv_sec 表示 秒, tv_usec 表示 微秒
对于 struct timeval的对象 可设置三种值
第一种 对象被设为 NULL ,对于select来说 表示 阻塞等待
(多个文件描述符任何一个都不就绪,select就一直不返回)
第二种 struct timeval对象定义出来,并将其中变量都设为0
对于select来说 表示 非阻塞等待
(多个文件描述符任何一个都不就绪,select就会立马出错 并返回)
第三种 struct timeval对象定义出来,并将其中变量设为 5 和 0
表示 5s以内 阻塞等待,否则 就 timeout(非阻塞等待) 一次
若在第3s时 有一个文件描述符就绪,则select就会返回 其中参数 timeout 表示 剩余的时间 2s(5-3=2)
readfds writefds exceptfds 参数的理解
readfds writefds exceptfds 这三个参数 是同质的
readfds 表示 读事件
writefds 表示 写事件
excepttfds表示 异常事件
三者类型都为 fd_set
fd_set是一个位图结构,用其表示多个文件描述符
通过比特位的位置, 就代表文件描述符数值是谁
位图结构想要使用 按位与、按位或 这些操作,必须使用操作系统提供的接口
FD_CLR :将指定的文件描述符从 指定的集合中清除
FD_ISSET:判断文件描述符是否在该集合中被添加
FD_SET: 将一个文件描述符添加到对应的set集合中
FD_ZERO:将文件描述符整体清空
以readfds 读事件为例
若放入 readfds 集合中,用户告诉内核 ,那些文件描述符对应的读事件需要由 内核 来关心
返回时,内核要告诉用户,那些文件描述符的读事件已经就绪
假设想让操作系统去关心八个文件描述符对应的事件
用户想告诉内核时,用户需 定义 fd_set 对象 rfds ,其中八个比特位设置为1
比特位的位置表示几号文件描述符
比特位被置1,则操作系统就需要关心 对应的几号文件描述符
如:需要关心 1-8号文件描述符,即查看是否就绪
当select返回时, 内核会告诉用户,rfds重置,并将 就绪的文件描述符 对应 的 比特位位置 置1
如: 3号和5号就绪,则对应比特位 位置 置1 ,表示3号和5号文件描述符 对应的内容就绪
select的返回值
select的返回值 同样也有三种情况
第一种 大于0
表示有几个文件描述符 是就绪的
第二种 等于0
进入timeout状态 ,即 5s以内没有任何一个文件描述符 就绪
第三种 小于0
等待失败 返回-1
如:想要等待下标为1 和2的文件描述符,但是下标为2的文件描述符根本不存在,就会等待失败
相关文章:
【计算机网络】高级IO之select
文章目录 1. 什么是IO?什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误?对错误码的进一步判断检测数据没有就绪时,返回做一些其他事情完整代码myt…...
如何设计一个高效的应用缓冲区【一个动态扩容的buffer类】
文章目录 前言一、为什么需要设计应用层缓冲区必须要有 output buffer目的问题output buffer的解决方案: 必须要有 input buffer总结 二、设计要点三、buffer设计思路基础函数关于iovec与readv readfd如何实现动态扩容 问题 前言 在上一个博客,我们介绍…...
图像处理初学者导引---OpenCV 方法演示项目
OpenCV 方法演示项目 项目地址:https://github.com/WangQvQ/opencv-tutorial 项目简介 这个开源项目是一个用于演示 OpenCV 方法的工具,旨在帮助初学者快速理解和掌握 OpenCV 图像处理技术。通过这个项目,你可以轻松地对图像进行各种处理&a…...
管道-匿名管道
一、管道介绍 管道(Pipe)是一种在UNIX和类UNIX系统中用于进程间通信的机制。它允许一个进程的输出直接成为另一个进程的输入,从而实现数据的流动。管道是一种轻量级的通信方式,用于协调不同进程的工作。 1. 创建和使用管道&#…...
【JavaEE基础学习打卡08】JSP之初次认识say hello!
目录 前言一、JSP技术初识1.动态页面2.JSP是什么3.JSP特点有哪些 二、JSP运行环境配置1.JDK安装2.Tomcat安装 三、编写JSP1.我的第一个JSP2.JSP执行过程3.在IDEA中开发JSP 总结 前言 📜 本系列教程适用于JavaWeb初学者、爱好者,小白白。我们的天赋并不高…...
使用序列到序列深度学习方法自动睡眠阶段评分
深度学习方法,用于使用单通道脑电图进行自动睡眠阶段评分。 def build_firstPart_model(input_var,keep_prob_0.5):# List to store the output of each CNNsoutput_conns []######### CNNs with small filter size at the first layer ########## Convolutionnetw…...
【算法】排序——选择排序和交换排序(快速排序)
主页点击直达:个人主页 我的小仓库:代码仓库 C语言偷着笑:C语言专栏 数据结构挨打小记:初阶数据结构专栏 Linux被操作记:Linux专栏 LeetCode刷题掉发记:LeetCode刷题 算法头疼记:算法专栏…...
Docker 容器监控 - Weave Scope
Author:rab 目录 前言一、环境二、部署三、监控3.1 容器监控 - 单 Host3.2 容器监控 - 多 Host 总结 前言 Docker 容器的监控方式有很多,如 cAdvisor、Prometheus 等。今天我们来看看其另一种监控方式 —— Weave Scope,此监控方法似乎用的人…...
Spring Boot集成redis集群拓扑动态刷新
项目场景: Spring Boot集成Redis集群,使用lettuce连接Cluster集群实例。 问题描述 redis其中一个节点挂了之后,springboot集成redis集群配置信息没有及时刷新,出现读取操作报错。 java.lang.IllegalArgumentException: Connec…...
COCI2022-2023#1 Neboderi
P9032 [COCI2022-2023#1] Neboderi 题目大意 有一个长度为 n n n的序列 h i h_i hi,你需要从中选择一个长度大于等于 k k k的子区间 [ l , r ] [l,r] [l,r],使得 g ( h l h l 1 ⋯ h r ) g\times (h_lh_{l1}\cdotsh_r) g(hlhl1⋯hr)最小&…...
由于找不到d3dx9_43.dll无法继续执行此代码怎么解决?全面解析d3dx9_43.dll
在使用计算机过程中,我们可能会遇到各种各样的问题。其中之一就是d3dx9_43.dll文件丢失的问题。这个问题通常会出现在运行某些应用程序或游戏时,导致程序无法正常启动或运行。那么,如何解决这个问题呢?小编将为您提供一些解决方案…...
Linux--网络编程-字节序
进程间的通信: 管道、消息队列、共享内存、信号、信号量。 特点:都依赖于linux内核。 缺陷:无法多机通信。 一、网络编程: 1、地址:基于网络,ip地址端口号。 端口号作用: 一台拥有ip地址的主机…...
python实现http/https拦截
python实现http拦截 前言:为什么要使用http拦截一、技术调研二、技术选择三、使用方法前言:为什么要使用http拦截 大多数爬虫玩家会直接选择API请求数据,但是有的网站需要解决扫码登录、Cookie校验、数字签名等,这种方法实现时间长,难度高。需求里面不需要高并发,有没有…...
农产品团购配送商城小程序的作用是什么
农产品覆盖稻麦油蛋等多种细分类目,各地区经营商家众多,随着人们生活品质提升,对食物的要求也在提升,绿色无污染无激素的农产品往往受到不少人喜爱,而在销售中,也有不少人选择自建商城线上经营。 通过【雨…...
使用van-dialog二次封装微信小程序模态框
由于微信小程序的wx.showModal不支持富文本内容,无法实现更灵活的展示效果,故需要进行二次封装 实现思路:使用van-dialog以及微信小程序的rich-text实现 代码如下: // index.wxml <van-dialoguse-slottitle"提示"s…...
生鲜蔬果同城配送社区团购小程序商城的作用是什么
生鲜蔬果行业作为市场主要支撑之一,从业商家众多的同时消费者也从不缺,尤其对中高城市,生鲜蔬果除了传统线下超市、市场经营外,线上更是受到大量消费者信任,而很多商家也是自建了生鲜蔬果商城多场景生意经营。 那么通…...
Unity实现设计模式——状态模式
Unity实现设计模式——状态模式 状态模式最核心的设计思路就是将对象的状态抽象出一个接口,然后根据它的不同状态封装其行为,这样就可以实现状态和行为的绑定,最终实现对象和状态的有效解耦。 在实际开发中一般用到FSM有限状态机的实现&…...
差分数组的应用技巧
前缀和技巧 针对的算法场景是不需要对原始数组进行修改的情况下,频繁查询某个区间的累加和。 差分数组 主要适用场景是频繁对原始数组的某个区间的元素进行增减。 相关题目 1094. 拼车 1109. 航班预订统计 370. 区间加法 # 1094. 拼车 class Solution:def carPool…...
斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 10 Mining Social-Network Graphs
来源:《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT。 Chapter 10 Mining Social-Network Graphs The essential characteristics of a social network are: There is a collection of entities that participate in the network. Typically, these entiti…...
DFS:842. 排列数字
给定一个整数 nn,将数字 1∼n1∼n 排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 输入格式 共一行,包含一个整数 nn。 输出格式 按字典序输出所有排列方案,每个方案占一行。 数据…...
pytorch之nn.Conv1d详解
自然语言处理中一个句子序列,一维的,所以使用Conv1d...
H5生成二维码
H5生成二维码: 1.引入js库,可自行点击链接复制使用 <script type"text/javascript" src"http://static.runoob.com/assets/qrcode/qrcode.min.js"></script>2.加入二维码占位区HTML <div id"qrCode">…...
Three.js加载360全景图片/视频
Three.js加载360全景图片/视频 效果 原理 将全景图片/视频作为texture引入到three.js场景中将贴图与球形网格模型融合,将球模型当做成环境容器使用处理视频时需要以dom为载体,加载与控制视频动作每次渲染时更新当前texture,以达到视频播放效…...
北大硕士7年嵌入式学习经验分享
阶段 1 大一到大三这个阶段我与大多数学生相同: 学习本专业知识(EE专业),学习嵌入式软件开发需要的计算机课程(汇编原理,计算机组成原理,操作系统,C语言等),…...
华为鸿蒙手表开发之动态生成二维码
华为鸿蒙手表开发之动态生成二维码 前言: 最近入职新公司,由于之前的哥们临时离职,走得很突然,所以没有任何交接和文档,临时顶上公司手表应用的上架,更换了新的密钥和key之后重新测试功能和流程ÿ…...
2023-09-28 monetdb-databae的概念和作用-分析
摘要: 每个数据库对于db,schema以及user,role都有一套自己的设计, 不同数据库间对于相同名字的东西例如database和schema可以说南辕北辙, 例如mysql中schema其实是database的同义词. 本文分析monetdb的database的概念和作用 database的概念和作用: 和mysql的database完全不同…...
2024级199管理类联考之数学基础(上篇)
管理类考试介绍 管理综合200分,时间3小时 数学:75分/25题,是拉开差距的核心模块 问题求解题:15个,5选一条件充分性判断:10个,结合两个条件选择答案 条件一充分,条件二不充分:A条件一不充分,条件二充分:B条件一充分,条…...
RFID技术引领汽车零部件加工新时代
RFID技术的兴起引领了汽车零部件加工领域的新时代,作为一种利用无线电频率进行自动识别的技术,RFID技术能够快速、准确地识别物体并获取相关数据,在汽车零部件加工中,RFID技术具有重要的应用价值,可以提高生产效率、降…...
python中使用matplotlib绘图
一、背景 当我们在写python程序时,不可避免的需要将数据可视化,也就是绘制出数据的曲线图,以便我们更直观的观察数据间的变化,和方便对比。此时就要用到matplotlib库了。 matplotlib官方给出的定义是: 翻译过来也就是…...
Qt Creator 使用技巧
使用技巧 功能快捷键解释Switch Header/SourceF4在同名的头文件和源程序文件之间切换Follow Symbol Under CursorF2变量:跳转到声明;函数:声明和定义切换Refactor Rename Symbol Under CursorCtrlShiftR改名称,将替换所有用到这个符号的地方RefactorAdd Definition…...
网站的建设与维护/广州seo招聘
描述 Description 尼克在一家养猪场工作,这家养猪场共有M间锁起来的猪舍,由于猪舍的钥匙都给了客户,所以尼克没有办法打开这些猪舍,客户们从早上开始一个接一个来购买生猪,他们到达后首先用手中的钥匙打开他所能打开的…...
防疫网站网页设计/网络营销推广8种方法
词向量模型 Word2Vec Skip-gram 模型是图嵌入模型 Random Walk 中要使用到的模型,因此先学习 Word2Vec 神经网络语言模型 NNLM 目标:根据给定的词序列,预测下一个会出现的词,如给定 “他”,“是”,“一个…...
用asp做的一个网站实例源代码/中国国家培训网官网入口
1787. 使所有区间的异或结果为零 难点1 根据异或运算的性质可得知, 最后满足条件的序列必然是这样的结构, a[0],a[1],...,a[k−1],....,a[n−1]a[0],a[1],...,a[k-1],....,a[n-1]a[0],a[1],...,a[k−1],....,a[n−1]前k个数的异或结果为 0, 并…...
佛山网络营销网站/福州网站seo公司
大家自我介绍做的多了,那幽默有个性的自我介绍该怎么写呢?以下是本站小编为大家带来的搞笑自我介绍 3篇,希望能帮助到大家!搞笑自我介绍1大家好!我叫-,有句话说“相聚是缘&r...2020-11-05阅读全文 >>大学生简历中如何自我介绍比较好呢。以下是…...
网站后端用什么软件做/建设网站的网站首页
原因:一个测试环境,nginxphp-fpm对外提供服务,测试人员访问的时候出现时快时慢的情况,慢时超过了正常网页的等待打开时间范围。重启nginx php-fpm后恢复,访问几次后又会慢查找思路:1,系统负载&a…...
昆明商城网站开发/热搜榜百度
介绍 Python 作为一门相当简洁的计算机语言,目前已经拥有诸多用户。而英文的帮助文件或多或少给英语水平不太好的用户带来了一定的不便。事实上,官网就有中文手册,为了大家的方便,这里下载下来中英两种格式的PDF文件,并…...