【Linux】几种典型的IO模型

2023-11-05

几种典型的IO模型

  • 常见IO场景----输入和输出。
  1. 读写文件 read/write/fread/fwrite
  2. 网络接收与发送 send/recv/sendto/recvfrom
  3. 上述两种场景都有一个共同点,就是最终都会和操作系统打交道
  • IO过程
  1. 等待数据
  2. 拷贝数据到用户空间

阻塞IO

1.当程序员在代码当中调用一个IO接口,如果内核还没有将数据准备好,IO接口就会阻塞等待,把这种IO的过程称之为阻塞IO

2. IO调用的返回,预示着一定拿到了想要的数据

非阻塞IO

当程序员在代码当中发起一个非阻塞IO调用,本质上就是判断IO数据是否准备完毕

  • 准备完毕:直接拷贝,IO调用返回
  • 没准备好:直接返回(因为实际想要拷贝数据的操作,并没有完成)搭配循环使用(采用轮询的方式),直到数据拷贝完毕

阻塞vs 非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。

阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回。

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

信号驱动IO

信号驱动IO就是在内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。

异步IO

异步IO是指数据的等待和数据的拷贝都是由内核来完成的,程序员在异步调用成功之后,可以直接操作拷贝好的数据。

aio_read 函数请求对一个有效的文件描述符进行异步读操作。这个文件描述符可以表示一个文件、套接字甚至管道。

任何IO过程中, 都包含两个步骤. 第一是等待, 第二是拷贝. 而且在实际的应用场景中, 等待消耗的时间往往都远远高于拷贝的时间。让IO更高效, 最核心的办法就是让等待的时间尽量少。

同步通信 vs 异步通信

同步和异步关注的是消息通信机制。

所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了,换句话说,就是由调用者主动等待这个调用的结果。

异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果,换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果,而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

另外,在表明多进程多线程的时候,也提到同步和互斥,这里的同步通信和进程之间的同步是完全不相干的概念。

进程/线程同步也是进程/线程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系,尤其是在访问临界资源的时候。

多路转接IO模型(多路复用)

多路转接的作用——可以监控多个文件描述符,当文件描述符当中有事件(读,写,异常)产生的时候,则通知调用者。

多路转接IO模型之slelect

/* According to POSIX.1-2001 */
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
                fd_set *exceptfds, struct timeval *timeout);

参数:

  1. nfds:取值为要监控的最大文件描述符数值+1
  2. readfds:读事件集合
  3. writefds:写事件集合
  4. exceptfds:异常事件集合
  5. timeout:
struct timeval{
long tv_sec;/*seconds秒*/
long tv_usec;/*microseconds微秒*/
  • 阻塞监控:传递的参数位 NULL
  • 非阻塞监控:传递的参数为 0
eg: tv_sec!= 0 && ty_usec!= 0
  • 带有超时事件的监控方式
eg: tv_sec!= 0 || ty_usec!= 0
  • 在超时时间范围内,是阻塞监控,如果监控的文件描述符对应的事件发生,则返回;超过超时时间还没有文件描述符对应的事件产生,则select也会返回

返回值:

  1. 大于0:监控成功了,返回的数字为有事件产生的文件描述符的个数也就是就绪的文件描述符个数
  2. 等于0:监控超时
  3. 小于0:监控出错

关于fd_set

1. d_set是一个结构体,这个结构体内部是一个数组,而数组的元素类型为long类型

2. fd_set在使用的时候并不是按照数组的方式来进行使用的,而是按照位图的方式来进行使用的

3. select接口中的readfds、writefds、exceptfds参数都是fd_set类型的,在Linux源码中fd_set表示如下:

fd_set事件集合位图的使用

fd_set事件集合分为读时间集合、写事件集合和异常事件集合,不同类型的集合代表着对该集合中文件描述符相应事件的关心,例如读事件集合,会关心相应的文件描述符的读事件。

1. select 最大监控的文件描述符的数量为1024个,对应监控的文件描述符数值的范围为:[0,1023]

2. 如果关心某个文件描述符的某个事件,则将文件描述符”添加”到对应的事件集合当中。添加的含义:将文件描述符对应的比特位置为1,则表示关心该文件描述符发生什么事件。

操作fd_set位图的接口

void FD_CLR(int fd, fd_set *set);

功能:将fd文件描述符,从事件结合set当中删除掉

本质:将fd文件描述符对应的比特位置为0

int  FD_ISSET(int fd, fd_set *set);

功能:判断fd是否存在在事件集合set当中

本质:判断fd文件描述符对应的比特位是否为1

返回值:

如果为0,则不在

如果为1,则存在

void FD_SET(int fd, fd_set *set);

功能:将文件描述符fd,设置到set事件集合当中

本质:将fd文件描述符对应的比特位置为1

void FD_ZERO(fd_set *set);

功能:将事件结合set清空

本质:将所有的比特位置为0

总结

当我们在调用上述接口操作事件集合的时候,本质上是在执行自己写的代码,说明当前执行流在用户空间,当我们调用select监控事件集合的时候,需要将事件集合拷贝到内核,让内核进行监控。

select监控成功之后,事件集合的文件描述符的变化。

select_tcp程序&select的优缺点:

  1. 优点
  • 可以跨平台,因为遵守的是Posix标准
  • 超时的监控时间可以精确到微妙

     2. 缺点

  • 监控的文件描述符的数量最大是1024,取决于内核当中的__FD_SETSIZE宏
  • select采用轮询遍历事件集合的方式,所以,随着监控文件描述符的增加,性能会下降
  • select的事件集合,在监控的时候,需要从用户空间拷贝到内核空间
  • select在监控成功之后,会将未就绪的文件描述符对应的比特位置为0,不方便下次监控

多路转接IO模型之poll

poll和select相比,没有了select跨平台的优势,除此之外,poll和后面要提到的epoll相比,没有epoll性能高。

相关接口

#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);

参数:

  1. fds:待要监控的事件结构数组
struct pollfd{
    int fd;/*file descriptor*/待要监控的文件描述符
    short events;/*requested events*/关心文件描述符的什么事件
        指定为POLLIN表示可读事件
        指定位POLLOUT表示可写事件
        如果关注的是可读并且可写事件,则
        需将POLLIN和POLLOUT使用按位或的方式连接起来
        eg:POLLIN | POLLOUT 
    short revents;/*returned events*/
    保存poll监控该文件描述符成功之后,该文件描述符产生的事件poll函数
    会对revents进行初始化,在传递参数的时候,程序员可以不用关心
};

     2. nfds:数组有效元素的个数,本质上也是告诉poll函数,监控的范围

     3. timeout:

  • <0:阻塞监控
  • ==0:非阻塞监控
  • >0:带有超时时间的监控方式,单位是毫秒

返回值:

  1. >0:表示就绪的文件描述符的个数
  2. ==0:超时
  3. <0:表示监控出错

poll的优缺点:

  1. 优点
  • 采用了事件结构的方式,不用针对文件描述符的每一种事件进行分类监控。
  • 要监控多少文件描述符,就定义多大的事件结构数组,数组的每一个元素的类型都是一个事件结构,可以对应一个文件描述符,并且将文件描述符关心的事件也填充进去了

    2. 缺点:

  • 不能跨平台
  • 同样采用轮询遍历的方式,随着文件描述符的增多,轮询效率就会下降(监控效率也就会下降)
  • 同样也是需要将事件结构数组从用户空间拷贝到内核空间,监控成功之后还需要从内核空间拷贝到用户空间

多路转接IO模型之epoll

epoll是当今公认的在linux操作系统下,性能最高的多路转接IO模型。

相关接口

1. 创建epoll句柄

#include <sys/epoll.h>
int epoll_create(int size);

作用:

创建epoll的操作句柄,在内核当中会创建一个eventpol结构体。

参数:

size:目前的内核版本当中这个size是毫无意义的,size定义了epoll维护的结构体的大小,epoll现在采用扩容的方式。(传参的时候只要不传递负数就行)

返回值:

返回了epol的操作句柄。

2. 添加/删除/修改事件结构

#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

作用:

向内核维护的红黑树当中添加或删除或修改事件结构。

参数:

  1. epfd:也就是epoll_create的返回值,epoll的操作句柄
  2. op(options):告知epoll_cl函数做什么操作
  • 添加:EPOLL_CTL_ADD
  • 删除:EPOLL_CTL_DEL
  • 修改:EPOLL_CTL_MOD

     3. fd:待操作的文件描述符

     4. event:事件结构

联合体epoll_data中的fd——保存的监控的文件描述符,是为了监控成功之后,让我们知道从双向链表当中获取的事件结构是属于哪一个文件描述符的,从而可以针对文件描述符已经产生的事件进行处理。

使用epoll_data_t的方式有两种:

a. 使用fd,但是不使用ptr。如果使用了fd,还使用ptr,ptr当中的值会覆盖fd的值,导致后续找不到该事件结构对应哪一个文件描述符。

b. 使用ptr,但是不使用fd注意:ptr的类型为void*,接收一个地址在传递给ptr的类型当中一定要包含一个字段为文件描述符,换言之,就是要传递一个结构体。

3. 监控

#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout;

参数:

  1. epfd:epoll的操作句柄
  2. events:事件结构数组

作用:从双向链表当中拷贝的事件结构放到events当中

例子:如果就绪了30个文件描述符,引申含义就是双向链表当中有30个事件结构

第一种:准备的事件结构数组大小大于就绪的文件描述符的个数

eg: struct epoll_event arr[50]

第二种:准备的事件结构数组大小等于就绪的文件描述符的个数

第三种:准备的事件结构数组大小小于就绪的文件描述符的个数

eg:struct epoll event arr[10];

    3. maxevents:告知epoll,当前最多能拷贝多少个就绪的事件结构到用户准备的事件结构数组当中,防止越界

    4. timeout:

<0:阻塞监控

==0:非阻塞监控

>0:带有超时时间的监控方式,单位是毫秒

返回值:

>0:表示就绪的文件描述符的个数

==0:超时

<0:表示监控出错

epoll工作原理

  1. epoll_create创建epol操作句柄,相当于在内核当中创建了一个struct eventpoll...}的结构体。
  2. epoll操作句柄就是用户用来操作eventpoll结构体的“钥匙”。
  3. 添加/删除/修改事件结构都是针对于这个红黑树而言的,意味着红黑树的每个节点都是一个事件结构,也就是epitem结构体。
  4. epoll监控是在遍历红黑树,红黑树的遍历效率是O(lgn),n为红黑树的高度。

socket就绪条件

读就绪

1. socket内核中, 接收缓冲区中的字节数, 大于等于低水位标记SO_RCVLOWAT. 此时可以无阻塞的读该文件描述符, 并且返回值大于0;

2. socket TCP通信中, 对端关闭连接, 此时对该socket读, 则返回0;

3. 监听的socket上有新的连接请求;

4. socket上有未处理的错误.

写就绪

1. socket内核中, 发送缓冲区中的可用字节数(发送缓冲区的空闲位置大小), 大于等于低水位标记SO_SNDLOWAT, 此时可以无阻塞的写, 并且返回值大于0;

2. socket的写操作被关闭(close或者shutdown). 对一个写操作被关闭的socket进行写操作, 会触发SIGPIPE信号;

3. socket使用非阻塞connect连接成功或失败之后;

4. socket上有未读取的错误.

LT:水平触发

如果文件描述符有事件产生,epoll就会一直进行通知,直到程序员将该文件描述符所对应的事件处理掉

就好比妈妈在弟弟打游戏时催他吃饭,如果他没有立即放下手机去吃饭,妈妈会时不时地过来催一下

ET:边缘触发

如果文件描述符有事件产生,只会通知一次。直到新的数据或者新连接到来才会再次触发

就好比爸爸在弟弟打游戏时催他吃饭没如果他没有立即放下手机去吃饭,如果他没有立即放下手机去吃饭,爸爸会再下一顿饭做好的时候再过来催他

epoll的使用场景

epoll的高性能, 是有一定的特定场景的. 如果场景选择的不适宜, epoll的性能可能适得其反

对于多连接, 且多连接中只有一部分连接比较活跃时, 比较适合使用epoll

例如, 典型的一个需要处理上万个客户端的服务器, 例如各种互联网APP的入口服务器, 这样的服务器就很适合epoll.

如果只是系统内部, 服务器和服务器之间进行通信, 只有少数的几个连接, 这种情况下用epoll就并不合适, 具体要根据需求和场景特点来决定使用哪种IO模型

epoll的优点

  1. 接口使用方便: 虽然拆分成了三个函数, 但是反而使用起来更方便高效。不需要每次循环都设置关注的文件描述符, 也做到了输入输出参数分离开
  2. 数据拷贝轻量: 只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中, 这个操作并不频繁(而select/poll都是每次循环都要进行拷贝)
  3. 事件回调机制: 避免使用遍历, 而是使用回调函数的方式, 将就绪的文件描述符结构加入到就绪队列中,epoll_wait 返回,直接访问就绪队列就知道哪些文件描述符就绪,这个操作时间复杂度O(1). 即使文件描述符数目很多, 效率也不会受到影响
  4. 没有数量限制: 文件描述符数目无上限
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】几种典型的IO模型 的相关文章

  • ioctl 命令的用户权限检查

    我正在实现 char 驱动程序 Linux 并且我的驱动程序中有某些 IOCTL 命令仅需要由 ADMIN 执行 我的问题是如何在 ioctl 命令实现下检查用户权限并限制非特权用户访问 IOCTL 您可以使用bool capable in
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • Google BQ:运行参数化查询,其中参数变量是 BQ 表目标

    我正在尝试从 Linux 命令行为 BQ 表目标运行 SQL 此 SQL 脚本将用于多个日期 客户端和 BQ 表目标 因此这需要在我的 BQ API 命令行调用中使用参数 标志 parameter 现在 我已经点击此链接来了解参数化查询 h
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh
  • Linux 上的 Pervasive ODBC 错误 [01000][unixODBC][驱动程序管理器]无法打开 lib '/usr/local/psql/lib/odbcci.so':找不到文件

    我正在尝试让 Pervasive v10 客户端 ODBC 在 Centos 6 上运行 据我所知 没有 64 位 ODBC 客户端 因此我必须使用 32 位客户端 我终于成功安装了它 但尝试使用时出现以下错误 isql v mydsn 0
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • GMail 421 4.7.0 稍后重试,关闭连接

    我试图找出为什么它无法使用 GMail 从我的服务器发送邮件 为此 我使用 SwiftMailer 但我可以将问题包含在以下独立代码中
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • Linux 为一组进程保留一个处理器(动态)

    有没有办法将处理器排除在正常调度之外 也就是说 使用sched setaffinity我可以指示线程应该在哪个处理器上运行 但我正在寻找相反的情况 也就是说 我想从正常调度中排除给定的处理器 以便只有已明确调度的进程才能在那里运行 我还知道
  • linux下如何从文本文件中获取值

    我有一些文本格式的文件 xxx conf 我在这个文件中有一些文本 disablelog 1 当我使用 grep r disablelog oscam conf 输出是 disablelog 1 但我只需要值1 请问你有什么想法吗 一种方法
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • ansible unarchive 模块如何查找 tar 二进制文件?

    我正在尝试执行一个 ansible 剧本 该剧本的任务是利用unarchive模块 因为我是在 OSX 上执行此操作 所以我需要使用它gnu tar 而不是bsd tar通常与 OSX 一起提供 因为BSD tar 不受官方支持 https

随机推荐

  • MPEG-4 Audio 关于esds 记录

    当解析Mp4的时候 会碰到这个esds 的box 这个box 有很多信息 当时是为了解决在MP4A中如何判断是acc还是 MP3 然后找到下面答案 https wiki multimedia cx index php title MPEG
  • ubuntu安装gcc-11提示Unable to locate package gcc-11

    使用 sudo apt get install gcc 11 想安装高版本的gcc但是怎么更新源都提示 Unable to locate package gcc 11 升级到ubuntu20 04也没解决 最后是添加了 sudo add a
  • html bottom html submit按钮表单控件与CSS美化

    一 html submit与bottom按钮基本语法结构 1 html submit按钮在input标签里设置type submit 即可设置此表单控件为按钮 submit按钮代码
  • HTTP协议-----------应用层协议

    一 引言 协议 就是一种约定 双方为了更好的完成某项活动 而一致遵守的约定 应用层协议 我们程序员自己定义的协议 最常见的应用层协议是http协议 二 URL和URI的区别与联系 URI统一资源标识符 用来唯一的标识一个资源 但不能定位 U
  • 主题配置和 消息发送(一)KafkaTemplate 的使用

    一 主题 1 1 配置主题 在应用程序上下文定义一个 KafkaAdmin Bean 它可以自动将主题添加到代理 通过这个Bean可以将 每一个新建的主题 Topic 添加到应用程序上下文中 下面是一个简单的示例 也可以创建 TopicBu
  • 计算机用户打印权限设置,如何设置打印机权限?

    2007 04 12 安装有打印机的电脑 开始 设置 打印机 右键点共享 没安装打印机的电脑 开始 设置 打印机 添加打印机 网络打印机 浏览打印机 双击workgroup下的用户 选中打印机 确定 第一步 在主机的 打印机和传真 文件夹中
  • linux内存swap什么意思,Linux中Swap与Memory内存简单介绍

    1 背景介绍 这篇文章介绍一下Linux中swap与memory 对于memory没什么可说的就是机器的物理内存 读写速度低于cpu一个量级 可是高于磁盘不止一个量级 因此 程序和数据若是在内存的话 会有很是快的读写速度 可是 内存的造价是
  • 函数和存储过程区别

    Waiting 转载于 https www cnblogs com Tim Liu archive 2011 04 26 2029500 html
  • 组合分类方法——装袋(bagging);提升(boosting)和AdaBoost;随机森林

    此篇文章仅作为个人学习笔记之用 内容来之数据挖掘技概念与技术 第三版 一书 由于编辑很是麻烦 我直接截图WPS下编辑好的内容 二 提升 boosting 和AdaBoost 三 随机森林
  • Linux Tips · VMWare上Linux运行很慢的解决

    目前的主流PC运行虚拟机 问题不是很大 然而在VMware上安装的有的Linux 比如Suse 10 2 却运行暴慢 文字明显是一行一行往上移的 其实这并不是因为程序运行慢 主要原因是启用了较高的显示设置 这些LINUX发行版主要目标是桌面
  • 线程池的主要处理流程及常用方法

    线程池的主要处理流程及常用方法 更多优秀文章 请扫码关注个人微信公众号或搜索 程序猿小杨 添加 一 主要处理流程 当调用线程池execute 方法添加一个任务时 threadPoolExecutor execute 具体代码如下 priva
  • cocos2dx opengl入门系列二-画一个三角形

    运行环境 mac10 12 2 xcode Version 8 2 1 cocos2dx x 3 13 1 代码 新建cocos2dx项目 具体操作官网有教程 新建好后 新建Test cpp 代码如下 Test cpp FirstTrian
  • 时序预测

    时序预测 MATLAB实现基于EMD GRU时间序列预测 EMD分解结合GRU门控循环单元 目录 时序预测 MATLAB实现基于EMD GRU时间序列预测 EMD分解结合GRU门控循环单元 效果一览 基本描述 模型描述 程序设计 参考资料
  • 【MySQL】数据处理函数

    函数 文本处理函数 日期和时间处理函数 数值处理函数 函数 SQL支持利用函数来处理数据 但是函数的可移植性不强 如果决定使用函数应该保证做好代码注释 以便以后能确切地知道所编写SQL代码的含义 大多SQL实现支持以下类型的函数 用于处理文
  • com.aspose.words 类LoadOptions

    com aspose words 类LoadOptions java lang Object com aspose words LoadOptions 直接已知子类 HtmlLoadOptions PdfLoadOptions RtfLoa
  • react native 上拖拽元素

    1 给一张效果图 2 具体代码如下 使用的就是react native里面的PanResponder 具体使用看 官网 这里主要两个知识点Animated 和 panResponder 我在componentDidMount初始 panRe
  • 企微外部群Api

    个人微信开发API 文档地址 wkteam gitbook io 所有个人号模块分析 登录模块 登录微控平台 member login 获取微信二维码 user login 执行微信登录 getIPadLoginInfo 获取联系人列表 群
  • Xpath和CSS选择器的使用详解

    Xpath与CSS选择器在爬虫中非常常见 下列我将描述一下它们的使用详情 安装Xpath和CSS选择器 Windows平台 pip install lxml Ubuntu平台 sudo apt get install python3 lxm
  • js的作用域和vue的作用域

    js有两种作用域 全局作用域和局部作用域 1 全局作用域 如果一个变量在所有函数外声明 那么就定义了一个全局作用域 2 局部作用域 有两种 函数作用域和块级作用域 函数作用域顾名思义就是在函数内定义的变量 而块级作用域则是 内let声明的变
  • 【Linux】几种典型的IO模型

    几种典型的IO模型 常见IO场景 输入和输出 读写文件 read write fread fwrite 网络接收与发送 send recv sendto recvfrom 上述两种场景都有一个共同点 就是最终都会和操作系统打交道 IO过程