高级IO【select、poll、epoll】

news2024/10/1 3:35:39

在这里插入图片描述

高山仰止,景行行止

文章目录

  • 五种IO模型
    • 阻塞I/O
    • 非阻塞I/O
    • I/O复用
    • 信号驱动I/O
    • 异步I/O
  • 同步通信与异步通信
    • 同步通信
    • 异步通信
  • 非阻塞IO
    • 基于fcntl实现setNonblock函数
    • 注意事项
  • IO多路转接—select
    • 文件描述符集合
    • timeval结构
    • 调用过程
    • 返回值
    • 缺点和局限性
  • IO多路转接—poll
    • struct pollfd 结构体
    • 返回值
    • 优缺点
  • IO多路转接—epoll
    • 原理和特点
    • 函数原型
      • epoll_create
      • epoll_ctl
      • epoll_wait
      • struct epoll_event 结构体
    • 工作模式
      • 水平触发
      • 边缘触发
    • epoll惊群问题
    • 优缺点
  • 总结

五种IO模型

在计算机网络中,I/O模型描述了数据在网络套接字和应用程序之间传输的方式。常见的五种I/O模型包括:阻塞I/O、非阻塞I/O、I/O复用、信号驱动I/O和异步I/O。

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

阻塞I/O

  • 原理:应用程序执行一个I/O操作时,如果数据未准备好,调用将会被阻塞,直到数据准备好为止。在数据被复制到应用程序缓冲区之前,应用程序一直等待,不会返回到主程序。
  • 应用场景:适用于单用户和单任务对性能要求不高的应用程序。

非阻塞I/O

  • 原理:应用程序执行一个I/O操作时,如果数据未准备好,调用立即返回一个错误。应用程序可以继续做其他事情,它必须不断地询问I/O操作是否完成。
  • 应用场景:适用于需要同时处理多个操作或任务的应用程序,但要求应用程序显式管理检查数据状态和重试操作。

I/O复用

  • 原理:使用select或poll等系统调用,允许应用程序监视多个文件描述符,一旦某个文件描述符就绪(读就绪或写就绪),能够通知程序进行相应的读写操作。这样,单个进程可以处理多个并发数据流。
  • 应用场景:适用于需要处理多个连接或多种网络条件的服务器应用,如Web服务器、数据库服务器。

信号驱动I/O

  • 原理:应用程序通过sigaction系统调用预先注册一个信号处理函数,当数据准备就绪时,系统产生一个SIGIO信号,应用程序随后开始I/O操作。
  • 应用场景:适用于希望避免轮询但又不希望I/O操作阻塞进程的场景。

异步I/O

  • 原理:应用程序发起一个I/O操作后立即返回,不需要等待I/O操作完成。当I/O操作完成后,应用程序会收到一个通知。
  • 应用场景:适用于需要高性能I/O处理的应用程序,特别是那些需要处理大量并发I/O操作或者对响应时间有严格要求的应用。

同步通信与异步通信

在计算机网络和系统设计中,同步通信和异步通信是两种基本的数据交换方式,它们在处理数据传输、通信过程控制、资源占用等方面有明显的不同。

同步通信

同步通信要求发送方和接收方在交换信息时必须同时处于就绪状态,即发送方在发送数据后,必须等待接收方的响应,才能继续进行下一步的操作。在同步通信中,双方的交互是实时进行的,这意味着任一方都必须在通信过程中等待对方,直到交换的信息被接收和确认。

  • 优点:数据的一致性和可靠性高,易于理解和实现。
  • 缺点:可能会导致资源的浪费,因为在等待响应期间,某些资源(如CPU、网络等)可能处于闲置状态。这种方式在处理速度较慢或负载较高的系统中效率不高。

异步通信

异步通信允许发送方在发送数据后不必立即等待响应,而是可以继续执行其他任务。接收方在接收和处理数据后,可以通过回调、事件、消息队列等方式通知发送方结果。在异步通信中,发送方和接收方不需要同时处理交换的信息,减少了等待时间。

  • 优点:提高了系统的整体效率和吞吐量,因为发送方在等待响应期间可以处理其他任务。非常适合于处理速度不均或多任务环境。
  • 缺点:编程模型更复杂,需要更多的错误处理机制。数据的一致性和顺序控制也更加困难。

注意,这里的同步通信与异步通信和线程的同步与互斥是完全不相干的概念,线程的同步是线程间的一种相互制约,相互协调的关系。

非阻塞IO

一般来说,文件描述符默认都是非阻塞的,如果想将文件描述符设置为非阻塞,可以使用函数fcntlfcntl 是 Unix 和类 Unix 系统中的一个重要的系统调用,全称是 “file control”。它提供了对文件描述符的各种控制操作,包括复制文件描述符、获取/设置文件描述符属性、文件锁定等。fcntl 是一个非常灵活的命令,其功能由命令参数指定。

语法

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );
  • fd: 文件描述符,是一个指向打开文件的引用。
  • cmd: 指定要执行的操作类型。
  • : 额外参数,其类型和数量取决于 cmd 参数的值。

常见用途和命令

  1. 复制文件描述符 (F_DUPFDF_DUPFD_CLOEXEC)

    • 创建一个新的文件描述符,作为旧文件描述符的副本。这通常用于重定向标准输入/输出或处理多线程中的文件描述符。
  2. 获取/设置文件描述符标志 (F_GETFDF_SETFD)

    • 获取或设置文件描述符的标志,例如设置 FD_CLOEXEC 标志,使得在执行 exec 调用新程序时关闭文件描述符。
  3. 获取/设置文件状态标志 (F_GETFLF_SETFL)

    • 获取或设置文件状态标志,如非阻塞 (O_NONBLOCK)、同步 (O_SYNC) 等。
  4. 文件锁定 (F_GETLK, F_SETLK, F_SETLKW)

    • 对文件或文件的一部分进行锁定,避免多个进程同时写入同一文件区域。F_SETLK 设置锁但如果无法立即获得锁则失败,F_SETLKW 则会等待直到锁被获取,而 F_GETLK 可以用来测试锁的状态。

示例

#include <iostream>
#include <unistd.h>
#include <fcntl.h>

int main()
{
    std::cout << ">>>>>> ";
    fflush(stdout);
    char buffer[1024];
    fcntl(0, F_SETFL, O_NONBLOCK);
    int ret = read(0, buffer, sizeof buffer);
    if(ret < 0)
    {
        std::cout << "read fail\n";
        exit(-1);
    }
    return 0;
}

在这里插入图片描述

基于fcntl实现setNonblock函数

void setNonblock(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    if(fl < 0)
    {
        std::cout << "fcntl getfl fail\n";
        exit(-1);
    }
    fl |= O_NONBLOCK;
    fcntl(fd, F_SETFL, fl);
}

注意事项

  • fcntl 的行为可能会根据不同的 UNIX 系统变化,特别是在文件锁定和某些命令的支持方面。
  • 在多线程环境中使用 fcntl 进行文件锁定时要小心,确保不会导致死锁。
  • 一些 fcntl 操作可能会因为文件类型而不被支持,比如对某些类型的特殊文件或网络套接字可能不支持文件锁定。

IO多路转接—select

select 函数是一种 I/O 多路复用机制,用于监视多个文件描述符的状态变化,以便在其中至少一个文件描述符就绪时进行读取、写入或异常处理。

select 函数的调用方式

#include <sys/select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  • nfds:要监视的文件描述符的数量(通常设置为要监视的最大文件描述符加一)。
  • readfdswritefdsexceptfds:分别是用于监视读取、写入和异常事件的文件描述符集合。
  • timeout:表示 select 函数的超时时间,如果为 NULL 则表示阻塞直到至少有一个文件描述符就绪。

文件描述符集合

fd_set 是一个位图(bitmask),用于表示一组文件描述符。通过宏函数 FD_ZEROFD_SETFD_CLRFD_ISSET,可以对 fd_set 进行操作,例如清零、设置、清除和测试文件描述符的状态。

在这里插入图片描述

在这里插入图片描述

timeval结构

timeval 结构是用于表示时间间隔的数据结构,通常用于设置超时时间或者记录时间间隔的信息。在 POSIX 系统中经常被使用,比如在网络编程中的超时设置,或者在计时功能中的时间间隔记录等。

timeval 结构的定义通常如下所示:

在这里插入图片描述

  • tv_sec:表示秒数部分,是一个 long 类型的整数,用于表示秒数。
  • tv_usec:表示微秒部分,是一个 long 类型的整数,用于表示微秒数(以毫秒为单位)。

timeval 结构主要用于设置超时时间,比如在调用 select 函数时设置超时时间,或者在 setsockopt 函数中设置超时选项。此外,它还可以用于记录时间间隔,比如在计时功能中记录程序执行的时间间隔。

调用过程

  1. 初始化fd_set:通过执行FD_ZERO(&set);初始化fd_set变量set,确保所有位都清零。这个步骤是必要的,因为它保证了set的起始状态是确定的,没有任何文件描述符被监视。

  2. 添加文件描述符到fd_set

    • 当执行FD_SET(fd, &set);时,如果fd=5,则set的第5位(从0开始计数)被设置为1,set的位表示变为0001,0000。
    • 如果继续添加fd=2fd=1,则相应的第2位和第1位也被设置为1,set现在变为0001,0011,表示fd=1fd=2fd=5都在监视之列。
  3. 调用select等待事件select(6, &set, NULL, NULL, NULL);调用会阻塞等待,直到监视的文件描述符之一(在这个例子中,是fd=1fd=2fd=5)上发生可读事件,或者发生了错误或异常条件。参数6表示监视的文件描述符范围从0到5,这是因为select的第一个参数应该是监视的文件描述符集中最大文件描述符加1。

  4. 检查select的结果:当select返回后,set会被修改以反映哪些文件描述符上发生了事件。如果fd=1fd=2上发生了可读事件,则它们在set中对应的位保持为1,表示它们准备好被读取。没有事件发生的fd=5对应的位会被清零,因为select会修改fd_set来仅包含那些发生了指定事件的文件描述符。

返回值

  • 如果至少有一个文件描述符就绪,select 函数返回就绪文件描述符的数量。
  • 如果超时时间到达,没有文件描述符就绪,select 返回 0。
  • 如果出现错误,select 返回 -1,并设置 errno 变量来指示错误类型。

缺点和局限性

  • 文件描述符数量限制:某些系统对单个进程能够监视的文件描述符数量有限制,这会限制 select 函数的使用。
  • 效率问题:select 函数需要遍历所有待监视的文件描述符,效率在文件描述符数量较大时可能不高。
  • 没有提供文件描述符状态改变的通知机制,需要不断轮询检查文件描述符的状态。

IO多路转接—poll

poll函数是一个I/O多路复用的系统调用,允许一个进程监视多个文件描述符,以确定是否可以执行读取、写入或是出错等操作,而无需阻塞等待。

函数原型:

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  • fds:指向一个struct pollfd数组的指针,该结构体用于描述要监视的文件描述符及其事件。
  • nfds:表示要监视的文件描述符的数量。
  • timeout:表示超时时间,以毫秒为单位。如果设置为负数,则poll会阻塞直到有文件描述符准备就绪;如果设置为0,则poll立即返回而不阻塞;如果大于0,则表示等待的最大时间。

struct pollfd 结构体

在这里插入图片描述

  • fd:要监视的文件描述符。
  • events:要监视的事件,包括 POLLIN(可读)、POLLOUT(可写)等。
  • revents:实际发生了的事件,由poll函数填充。

返回值

  • -1:发生错误,可以通过 errno 变量查看具体错误原因。
  • 0:超时。
  • > 0:返回就绪的文件描述符数量。

优缺点

优点:

  1. 支持大量文件描述符: poll能够有效地处理大量的文件描述符,通常没有文件描述符数量的限制。

  2. 可移植性: poll是POSIX标准的一部分,在大多数主流操作系统上都有支持,包括Linux、Windows和Unix等。

  3. 简单易用: poll的接口相对简单,并且易于使用和理解,只需要准备一个struct pollfd数组来描述要监视的文件描述符和事件。

缺点:

  1. 效率问题: 尽管poll在处理大量文件描述符时比select效率更高,但在某些情况下仍可能存在效率问题,特别是当文件描述符数量非常大时。

  2. 性能下降: poll是一种轮询机制,需要遍历所有的文件描述符来检查状态变化,因此随着文件描述符数量的增加,性能可能会下降。

  3. 没有就绪文件描述符数量的返回值: poll函数只返回就绪的文件描述符的数量,而不提供就绪的文件描述符的具体信息,需要通过遍历struct pollfd数组来获取。

IO多路转接—epoll

epoll是Linux提供的一种I/O多路复用机制,用于有效地处理大量的文件描述符,并且能够高效地监视多个文件描述符的状态变化。

原理和特点

数据结构:

  • 红黑树(Red-Black Tree): epoll使用红黑树来存储需要监视的文件描述符(FD)。
  • 就绪链表(Ready List): 用于存储发生事件的文件描述符。

主要流程:

  1. 创建epoll实例: 用户调用epoll_create函数创建一个epoll实例,并返回一个文件描述符,用于操作该实例。

  2. 添加文件描述符: 用户通过epoll_ctl函数将需要监视的文件描述符添加到epoll实例中。

  3. 等待事件发生: 用户调用epoll_wait函数等待事件发生,内核会阻塞进程直到有文件描述符发生事件。

  4. 事件通知: 当文件描述符上有事件发生时,内核会将发生事件的文件描述符加入到就绪链表中,并唤醒等待的进程。

  5. 处理事件: 用户从就绪链表中获取发生事件的文件描述符,并处理相应的事件。

工作原理:

  • 当调用epoll_wait函数时,内核会遍历红黑树,找到有事件发生的文件描述符,并将其添加到就绪链表中。
  • 用户可以通过就绪链表获取发生事件的文件描述符,然后进行相应的处理。

函数原型

epoll_createepoll_ctlepoll_wait,它们是使用epoll进行事件驱动的核心。

epoll_create

int epoll_create(int size);
  • 功能: 创建一个epoll实例,并返回一个文件描述符。
  • 参数:
    • size:指定epoll实例的大小,通常设置为一个大于0的数即可,但实际上内核会忽略这个参数。
  • 返回值:
    • 如果成功,返回一个新的文件描述符,代表创建的epoll实例;
    • 如果失败,返回-1,并设置errno。

epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  • 功能: 控制epoll实例,用于添加、修改或删除要监视的文件描述符。
  • 参数:
    • epfdepoll实例的文件描述符,由epoll_create返回。
    • op:操作类型,可以是EPOLL_CTL_ADDEPOLL_CTL_MODEPOLL_CTL_DEL,分别表示添加、修改或删除文件描述符。
    • fd:要进行操作的文件描述符。
    • event:要监视的事件,是一个struct epoll_event结构体。
  • 返回值:
    • 如果成功,返回0;
    • 如果失败,返回-1,并设置errno。

epoll_wait

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  • 功能: 等待事件发生,返回发生了事件的文件描述符。
  • 参数:
    • epfdepoll实例的文件描述符,由epoll_create返回。
    • events:用于存储发生事件的文件描述符和事件的数组。
    • maxeventsevents数组的最大容量。
    • timeout:等待超时时间,单位为毫秒,传入-1表示永久等待。
  • 返回值:
    • 如果成功,返回发生了事件的文件描述符数量;
    • 如果超时,返回0;
    • 如果出错,返回-1,并设置errno。

这些函数共同构成了epoll的核心API,允许用户控制监视的文件描述符和等待事件的情况,从而实现高效的事件驱动机制。

struct epoll_event 结构体

在这里插入图片描述

  • events:要监视的事件,包括 EPOLLIN(可读)、EPOLLOUT(可写)等。
  • data:用户数据,通常是文件描述符。

在这里插入图片描述

工作模式

epoll具有两种工作模式:水平触发(Level-Triggered)和边缘触发(Edge-Triggered)

水平触发

  • 特点:
    • 当文件描述符准备好时,epoll_wait返回,并且在下次仍然会触发。
    • 如果文件描述符处于就绪状态,但未处理完全部数据,下次epoll_wait仍然会返回该文件描述符。
  • 适用情况:
    • 适用于普通的I/O事件处理,适用性广泛,使用比较灵活。
  • 优点:
    • 兼容性好,适用于大多数场景。
  • 缺点:
    • 容易出现事件重复通知,可能导致性能损耗。

边缘触发

  • 特点:
    • 当文件描述符状态发生变化时,epoll_wait返回,但只返回一次,需要重新注册。
    • 仅在状态变化时通知用户,不会重复通知相同的事件。
  • 适用情况:
    • 适用于需要精确控制事件处理的高性能场景。
  • 优点:
    • 减少了事件重复通知,提高了效率。
  • 缺点:
    • 需要用户自行管理文件描述符的状态变化,可能较为复杂。

选择建议:

  • 如果对于同一个文件描述符的事件可能会频繁发生而且需要一直关注,可以选择水平触发模式。
  • 如果希望系统更高效地处理事件,并且能够减少事件通知次数,可以选择边缘触发模式。

epoll惊群问题

"惊群问题"是在使用多线程或多进程并发处理网络连接时可能遇到的一种性能问题。它的主要原因是内核中的事件通知机制会通知所有等待相同事件的线程或进程,导致多个线程或进程同时被唤醒,竞争处理同一个事件,造成资源浪费和性能下降。

epoll 中,惊群问题通常指当一个文件描述符上的事件就绪时,epoll 调用 epoll_wait 返回,然后多个线程或进程被唤醒来处理这个事件,但实际上只有一个线程或进程能够处理该事件,其他的则白白被唤醒了。

解决 epoll 中的惊群问题,可以采取以下措施:

  1. 多线程下,确保只有一个线程在epoll_wait,然后有该线程对事件进行分配给其他线程处理。
  2. 多进程下,使用一把全局互斥锁,在子进程进行epoll_wait前,则先获取锁。

优缺点

优点:

  1. 高性能: epoll使用红黑树和就绪链表管理文件描述符,能够高效地处理大量的并发连接,适用于高性能的网络服务器。
  2. 支持大规模并发: epoll不受文件描述符数量的限制,适用于处理大规模的并发连接。
  3. 事件驱动: epoll_wait函数阻塞进程直到有事件发生,避免了轮询的开销,提高了系统的效率。
  4. 边缘触发模式: epoll支持边缘触发模式,可以减少事件通知次数,提高了系统的性能。

缺点:(基本没什么缺点,挑刺)

  1. Linux专有: epoll是Linux特有的系统调用,在其他操作系统上无法直接使用。
  2. 复杂性: 使用epoll相对于selectpoll来说,需要更复杂的编程模型和更深入的理解,使用不当容易导致性能问题或者编程错误。
  3. API变化: 随着Linux内核版本的更新,epoll的API可能会发生变化,需要及时了解和适应新的API。

总结

特性selectpollepoll
跨平台性良好良好仅适用于Linux系统
效率低效,性能随文件描述符数量增加而下降低效,性能随文件描述符数量增加而下降高效,性能不随文件描述符数量增加而下降
最大文件描述符数有限制无限制无限制
编程复杂度简单简单相对较高
边缘触发
适用场景小规模并发连接小规模并发连接大规模并发连接

从上表可以看出,epoll在性能、文件描述符数量无限制和支持边缘触发等方面具有优势,适用于大规模并发连接的场景。select和poll在跨平台性和简单易用性方面具有优势,但在处理大规模并发连接时性能较差。选择合适的I/O多路复用方式应根据具体的应用需求和环境来决定。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1505767.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java共享问题 、synchronized 线程安全分析、Monitor、wait/notify

文章目录 1.共享带来的问题1.1 临界区 Critical Section1.2 竞态条件 Race Condition 2. synchronized语法及理解2.1 方法上的 synchronized 3.变量的线程安全分析3.1.成员变量和静态变量是否线程安全&#xff1f;3.2.局部变量是否线程安全&#xff1f;3.2.1 局部变量线程安全分…

三阶导数在生活中应用

“鲍威尔还表示&#xff0c;美联储将在某个时候放慢&#xff08;利率&#xff09;加息步伐” 这是参考三阶导数&#xff08;贷款义务基础&#xff0c;利率一阶导数&#xff0c;利率变化二阶导数&#xff0c;利率变化速度三阶导数&#xff09;。 是否还有其他有趣的例子&#…

算法详解——leetcode150(逆波兰表达式)

欢迎来看博主的算法讲解 博主ID&#xff1a;代码小豪 文章目录 逆波兰表达式逆波兰表达式的作用代码将中缀表达式转换成后缀表达式文末代码 逆波兰表达式 先来看看leetcode当中的原题 大多数人初见逆波兰表达式的时候大都一脸懵逼&#xff0c;因为与平时常见的表达式不同&am…

华为配置DHCP Snooping防止DHCP Server仿冒者攻击示例

配置DHCP Snooping防止DHCP Server仿冒者攻击示例 组网图形 图1 配置DHCP Snooping防止DHCP Server仿冒者攻击组网图 DHCP Snooping简介配置注意事项组网需求配置思路操作步骤配置文件 DHCP Snooping简介 在一次DHCP客户端动态获取IP地址的过程中&#xff0c;DHCP Snoopi…

基于Vue的娱讯移动端APP前端设计与实现

目 录 摘 要 Abstract 引 言 1绪论 1.1课题背景及目的 1.1.1移动端APP发展简介 3 1.1.2移动端APP的优势 3 1.2前端开发相关技术 1.2.1前端开发工具介绍 3 1.2.2 前端开发相关技术介绍 4 1.3本章小结 2系统分析 2.1功能需求分析 2.2系统工作流程 2.3本章小结 3系统设…

Linux 之七:Linux 防火墙 和进程管理

防火墙 查看防火墙 查看 Centos7 的防火墙的状态 sudo systemctl status firewalld。 查看后&#xff0c;看到active(running)就意味着防火墙打开了。 关闭防火墙&#xff0c;命令为&#xff1a; sudo systemctl stop firewalld。 关闭后查看是否关闭成功&#xff0c;如果…

python的scripts文件夹作用

Windows系统&#xff1a; Scripts文件夹通常位于Python的安装目录下&#xff0c;如C:\Python\Scripts。该文件夹内包含了各种有用的工具&#xff0c;例如pip、virtualenv等&#xff0c;这些工具有助于管理和配置Python环境和依赖包。 Linux系统&#xff1a; 在Linux系统中&…

【大厂AI课学习笔记NO.69】使用开源管理仓库

了解了开源框架&#xff0c;开源项目&#xff0c;今天来学习开源管理仓库。 我们先说Git&#xff0c;开源的版本管理分布式系统。 GitHub&#xff0c;则是世界上最大的代码托管平台&#xff0c;面向开源和私有项目托管。 有的人总是分不清这两个&#xff0c;其实一个是版本管…

凌鲨微应用架构

微应用是静态网页加上凌鲨提供的扩展能力而形成的一种应用&#xff0c;主要特点是开发便捷&#xff0c;安全。 微应用架构 组件说明 名称 说明 微应用 webview窗口&#xff0c;显示web服务器上的页面 接口过滤器 根据权限配置,屏蔽非授权接口访问 接口提供者 tauri注入…

循序渐进丨MogDB 数据库特性之动态数据脱敏机制

数据脱敏是行之有效的数据库隐私保护方案之一&#xff0c;可以在一定程度上限制非授权用户对隐私数据的窥探。动态数据脱敏机制是一种通过定制化脱敏策略来实现对隐私数据保护的技术&#xff0c;可以在保留原始数据的前提下有效地解决非授权用户对敏感信息访问的问题。当管理员…

C#,蛇梯问题(Snake and Ladder Problem)的算法与源代码

1 蛇梯问题 Snake and Ladder Problem 给定一个蛇梯板&#xff0c;找出从源单元格或第一个单元格到达目标单元格或最后一个单元格所需的最小掷骰次数。基本上&#xff0c;玩家可以完全控制掷骰子的结果&#xff0c;并希望找出到达最后一个单元格所需的最小掷骰次数。 如果玩…

基于鳑鲏鱼优化算法(Bitterling Fish Optimization,BFO)的无人机三维路径规划

一、无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化飞行…

gradle下载太慢者超时!国内镜像可以直接下载

# 解决Gradle下载过慢问题的有效方式&#xff1a;使用国内镜像站点 在开发过程中&#xff0c;我们经常会遇到Gradle下载速度缓慢或超时的问题。作为一个强大而流行的构建工具&#xff0c;Gradle是许多项目中必不可少的一部分。然而&#xff0c;由于官方下载地址可能受网络限制…

Windows10/11配置WSL(Ubuntu)环境

文章目录 WSL介绍WSL部署扩展&#xff1a;辅助工具Windosw Terminal安装下载 WSL介绍 传统方式获取Linux操作系统&#xff0c;是安装完整的虚拟机及镜像环境&#xff0c;例如虚拟机VMware 而使用WSL,可以以非常轻量化的方式&#xff0c;得到Linux系统环境 它无需单独虚拟一套硬…

React 19 Cheat Sheet

React 19让构建网站和应用程序变得更容易&#xff0c;更好。有了很酷的新东西&#xff0c;比如React编译器、Actions API和更好的Hooks&#xff0c;编写代码变得更快&#xff0c;管理应用程序的数据变得更简单 React 19让构建网站和应用程序变得更容易&#xff0c;更好。有了很…

vue组件之间通信方式汇总

方式1&#xff1a;props和$emit props和$emit仅仅限制在父子组件中使用 1.props&#xff1a;父组件向子组件传递数据 1.1 代码展示 <template><div><!-- 这是父组件 --><div>父组件中的基本数据类型age的值是:{{this.age}}</div><div>…

C++的一些基础语法

前言&#xff1a; 本篇将结束c的一些基础的语法&#xff0c;方便在以后的博客中出现&#xff0c;后续的一些语法将在涉及到其它的内容需要用到的时候具体展开介绍&#xff1b;其次&#xff0c;我们需要知道c是建立在c的基础上的&#xff0c;所以c的大部分语法都能用在c上。 1.…

【Docker】容器的概念

容器技术&#xff1a;容器技术是基于虚拟化技术的&#xff0c;它使应用程序从一个计算机环境快速可靠地转移到另一个计算机环境中&#xff0c;可以说是一个新型地虚拟化技术。 一、docker容器 Docker:是一个开源地容器引擎Docker 是一种轻量级的容器化技术&#xff0c;其主要原…

雷赛控制卡获取轴当前位置的值不正确问题处理

现像 从雷赛控制卡中获取当前轴位置值时发现轴在向零点的右边走时显示的值是负数。正常来就一般是要反馈正数的。一般轴零点右边是正方向&#xff0c;限位是正限位&#xff0c;反馈的位置也应该是正数。 如果雷赛软件中的【单轴参数】中的基本设置中的【脉冲模式】设置的是对的…

【神经网络与深度学习】LSTM(Long Short-Term Memory)神经网络模型

概述 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种特殊的循环神经网络&#xff08;RNN&#xff09;结构&#xff0c;通常被用于处理和学习时间序列数据。因此&#xff0c;LSTM属于深度学习领域中的一种神经网络模型。 在深度学习中&#xff0c;LSTM被广泛应用于…