Linux:多路转接(上)——select
目录
一、select接口
1.认识select系统调用
2.对各个参数的认识
二、编写select服务器
一、select接口
1.认识select系统调用
int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, struct timeval* timeout);
-
头文件:sys/time.h、sys/types.h、unistd.h
-
功能:select负责IO中多个描述符等的那部分,该函数会在描述符的读写异常事件就绪时,提醒进程进行处理。
-
参数:后面讲。
-
返回值:返回值大于0表示有相应个文件描述符就绪,返回值等于0表示没有文件描述符就绪,超时返回,返回值小于0表示select调用失败。
2.对各个参数的认识
(1)struct timeval* timeout
它是一个struct timeval类型的类指针,定义如下:
struct timeval
{time_t tv_sec; /* Seconds. */suseconds_t tv_usec; /* Microseconds. */
};
内部有两个成员,第一个是秒,第二个是微秒。
这个timeout如果传参nullptr,默认select阻塞等待,只有当一个或者多个文件描述符就绪时才会通知上层进程去读取数据。
参数如果传入struct timeval timeout = {0, 0},秒和微秒时间都设置成0,此时select就使用非阻塞等待,需要程序员编写轮询检测代码。
参数如果设置了具体值,如struct timeval timeout = {5, 0},时间设置成5秒,select就会在5秒内阻塞等待,如果在5秒内有文件描述符就绪,则通知上层;如果没有则超时返回。
(2)int nfds
表示要等待的所有文件描述符中的最大值加一。
假设要等待3个文件描述符,分别为3、4和7,则传参时就需要传7+1=8给nfds。
(3)fd_set
fd_set是一个等待读取就绪文件描述符的位图。
它的每一个比特位代表一个文件描述符,比特位的状0和1表示该比特位是否被select监听。
下面就是fd_set位图的示意图,表示偏移量为1、3、5的三个文件描述符需要被select监视。
fd_set类型的大小为128字节,每个字节有8个比特位,所以fd_set类型能包含1024个比特位,也表明select最多能监视1024个文件描述符。
虽然我们知道fd_set属于位图结构,但是我们并不清楚其内部实现。
所以在对位图数据进行增删 查改时一定要使用系统提供的增删查改接口。
FD_ZERO(fd_set *fdset);——将fd_set清零,集合中不含任何文件描述符,可用于初始化
FD_SET(int fd, fd_set *fdset);——将fd加入fd_set集合
FD_CLR(int fd, fd_set *fdset);——将fd从fd_set集合中移除
FD_ISSET(int fd, fd_set *fdset);——检测fd是否在fd_set集合中,不在则返回0
(4)fd_set* reads
fd_set* reads、fd_set* writefds、fd_set* exceptfds中间的这三个参数属于输出型参数。
在这里我以fd_set* reads为例进行讲解。
fd_set* reads表示读位图,传递的参数表示需要被监视的文件描述符,而且select只关心是这些文件描述符内否有数据需要被读取。
假如说,我们定义了一个fd_set变量使用FD_SET将文件描述符1、3、5填入变量,最后将该变量的指针传入函数。
在select正常返回或超时返回时,它会更改这个变量。
比方说,select调用完成后将位图改为下面的样式,表明文件描述符1、3准备好了,可以由系统调用去读取。由于两个文件描述符就绪,所以返回值为2。
在下次进行select调用时,我们还能再次修改该位图,增加或减少需要监听的文件描述符。
select再次返回时,该位图依旧会被修改,从而指示在这一次调用后哪些文件描述符已经准备就绪。
也就是说,传参时这个位图代表需要监听的描述符,调用返回时这个位图代表已就绪的文件描述符。
fd_set* reads与fd_set* writefds、fd_set* exceptfds在使用上是一样的,只不过fd_set* writefds只关心进程向文件描述符中写数据的操作,而fd_set* exceptfds只关心该文件描述符是否出现了错误。
它们也会以同样的方式修改自己对应的fd_set变量,从而达到通知进程的目的。
二、编写select服务器
selectserver.hpp:服务器
socket.hpp:套接字
text.cpp:启动服务器
socket.hpp
/** @Author: 码农 2646995216@qq.com* @Date: 2025-03-18 15:13:58* @LastEditors: 码农 2646995216@qq.com* @LastEditTime: 2025-03-18 23:49:48* @FilePath: /netcomputer/socket.hpp* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE*/
#pragma once
#include <iostream>
#include <string>
#include <unistd.h>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>using namespace std;enum
{Socket_false = 1, // 创建套接字失败Bind_false, // 绑定失败Listen_false, // 监听失败Accept_false, // 等待客户端连接失败Connect_false, // 连接服务器失败
};const int backlog = 5;class Sock
{
public:// 构造函数Sock(int listensockfd = -1): _listensockfd(listensockfd){}// 创建套接字void Socket(){_listensockfd = socket(AF_INET, SOCK_STREAM, 0); // AF_INET:代表IPv4,SOCK_STREAM:代表Tcp协议if (_listensockfd < 0){cout << "socket false" << endl;exit(Socket_false);}cout << "socket success" << endl;//打开端口复用保证程序退出后可以立即正常启动int opt = 1;setsockopt(_listensockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));}// 绑定,传端口号,是因为sockaddr_in需要,用来保存客户端的IP地址和端口号void Bind(uint16_t port){sockaddr_in local;memset(&local, 0, sizeof(&local)); // 初始化local.sin_family = AF_INET;local.sin_port = htons(port); // 将端口号转化为网络字节序local.sin_addr.s_addr = INADDR_ANY; // 代表0.0.0.0socklen_t len = sizeof(local);int n = bind(_listensockfd, (struct sockaddr *)&local, len);if (n < 0){cout << "bind false" << endl;exit(Bind_false);}cout << "bind success" << endl;}// 监听void Listen(){int n = listen(_listensockfd, backlog);if (n < 0){cout << "listen false" << endl;exit(Listen_false);}cout << "listen success" << endl;}// 如果没有客户端连接服务端,则accept会阻塞等待新连接,等待客户端的连接// 可以通过Accept函数,拿到客户端的ip地址,端口号,用于网络通信的描述符sockint Accept(string &clientip, uint16_t &clientport){sockaddr_in addr;socklen_t len = sizeof(addr);// 调用accpt函数,会将客户端的数据保存在addr中(ip,port)int sock = accept(_listensockfd, (struct sockaddr *)&addr, &len);if (sock < 0){cout << "accept false" << endl;exit(Accept_false);}cout << "accept success" << endl;// 将客户端的ip和port,放入clientip = inet_ntoa(addr.sin_addr); // 将in_addr_t类型的ip转为char*类型的ipclientport = ntohs(addr.sin_port); // 将其转为主机字节序return sock;}// 连接服务器,这个ip和port是我们在启动客户端的时候输入的bool Connect(string &ip, uint16_t &port){sockaddr_in peer;memset(&peer, 0, sizeof(peer));//初始化peer.sin_family = AF_INET;peer.sin_addr.s_addr = inet_addr(ip.c_str());peer.sin_port = htons(port);socklen_t len = sizeof(peer);int n = connect(_listensockfd, (struct sockaddr *)&peer, len);if (n < 0){cout << "connect false" << endl;//exit(Connect_false);return false;}cout << "connect success" << endl;return true;}//关闭网络文件适配符void Close(){close(_listensockfd);}//获取网络文件适配符int Getlistensockfd(){return _listensockfd;}// 析构函数~Sock(){}private:int _listensockfd; // 网络文件适配符
};
selectserver.hpp
#include<iostream>
#include"socket.hpp"
#include <sys/select.h>
#include <sys/time.h>const int fd_num_max=1024;
const uint16_t default_fd = -1;//将所有需要管理的文件描述符放入一个数组,-1是数组中的无效元素class SelectServer
{
public://构造函数SelectServer(uint16_t port=default_fd):_port(port){//初始化数组for(int i=0;i<fd_num_max;i++){fd_array[i]=default_fd;}}//初始化void Init(){_listensock.Socket();_listensock.Bind(_port);_listensock.Listen();}//处理客户端发来的链接请求void Accepter(){//客户端发来请求,建立链接string clienttip;uint16_t clientport=0;int sock=_listensock.Accept(clienttip,clientport);if(sock<0){cout<<"Accepter false"<<endl;return;}cout<<"Accepter success,sock: "<<sock<<endl;//由于fd_array[0]存储了监听文件描述符,即从1开始int pos=1;for(;pos<fd_num_max;pos++){//找到数组中没有,放入文件描述符的位置if(fd_array[pos]!=default_fd)continue;elsebreak;}//数组中文件描述符存满了if(pos==fd_num_max){cout<<"server is full"<<endl;close(sock);}else{//将客户端建立链接的位置放入数组中,以便下次存入位图中,让select监听该位置fd_array[pos]=sock;//打印数组中的文件描述符PrintFd();}}//处理客户端发来的信息void Recver(int fd,int pos){//用来存储客户端发来的数据char buffer[1024];ssize_t n=read(fd,buffer,sizeof(buffer)-1);//最后一个换行符不要if(n>0){buffer[n]=0;cout<<"get a messge: "<<buffer<<endl;}else if(n==0){cout<<"client quit,me too"<<endl;close(fd);//由于客户端退出了,即该文件描述符不需要被select监听,即将其关闭fd_array[pos]=default_fd;}else{cout<<"read false"<<endl;close(fd);fd_array[pos]=default_fd;}}//处理已经就绪的文件描述符void Hander(fd_set& rfds){for(int i=0;i<fd_num_max;i++){int fd=fd_array[i];//相等,代表该位置没有文件描述符,即跳过if(fd==default_fd) continue;//判断该文件描述符,有没有被设置进位图中if(FD_ISSET(fd,&rfds)){//客户端要与服务器建立连接if(fd==_listensock.Getlistensockfd()){Accepter();}else//代表该文件描述符,已经发来了信息,需要我们去读{Recver(fd,i);}}}}//启动服务器void Start(){int listensock=_listensock.Getlistensockfd();//保存监听套接字fd_array[0]=listensock;将listen套接字放在第一个,因为在程序运行的全过程中都不会被修改while(true){fd_set rfds;//创建位图FD_ZERO(&rfds);//将位图初始化int maxfd=fd_array[0];//由于select的第一个参数,需要最大文件描述符+1for(int i=0;i<fd_num_max;i++){//如果这个位置等于-1,则说明该位置没有文件描述符,即该位置不需要被select监视if(fd_array[i]==default_fd) continue;//走到这里,说明该位置需要被监视,即将在位图中的该位置设置为1,代表该位置需要被监视FD_SET(fd_array[i],&rfds);//找到最大的文件描述符if(maxfd<fd_array[i]){maxfd=fd_array[i];cout<<"maxfd update"<<endl;}//第一个参数代表秒,第二个参数代表毫秒//struct timeval timeout={5,0};代表每过多少时间,select就会读取一次,不会阻塞等待//返回已经就绪的个数int n=select(maxfd+1,&rfds,nullptr,nullptr,nullptr/*&timout*/);//非阻塞等待switch(n){case 0:cout<<"time out"<<endl;break;case -1:cout<<"select false"<<endl;break;default:cout<<"get a new link!!"<<endl;Hander(rfds);//去处理已经就绪了的文件描述符break;}}}}//打印void PrintFd(){cout<<"online fd list: ";for(int i=0;i<fd_num_max;i++){if(fd_array[i]==default_fd)continue;cout<<fd_array[i]<<" ";}cout<<endl;}//析构函数~SelectServer(){_listensock.Close();}private:uint16_t _port; //端口号Sock _listensock; //套接字int fd_array[fd_num_max]; //用于储存所有需要管理的文件描述符的数组
};
text.cpp
#include "selectserver.hpp"
#include <memory>int main(int argv,char* args[])
{int port=stoi(args[1]);std::unique_ptr<SelectServer> svr(new SelectServer(port));svr->Init();svr->Start();return 0;
}
运行:
相关文章:
Linux:多路转接(上)——select
目录 一、select接口 1.认识select系统调用 2.对各个参数的认识 二、编写select服务器 一、select接口 1.认识select系统调用 int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, struct timeval* timeout); 头文件:sys/time.h、sys/ty…...
如何解决DDoS攻击问题 ?—专业解决方案深度分析
本文深入解析DDoS攻击面临的挑战与解决策略,提供了一系列防御技术和实践建议,帮助企业加强其网络安全架构,有效防御DDoS攻击。从攻击的识别、防范措施到应急响应,为网络安全工作者提供了详细的操作指引。 DDoS攻击概览:…...
机器学习Python实战-第三章-分类问题-3.决策树算法
目录 3.3.1 原理简介 3.3.2 算法步骤 3.3.3 实战 3.3.4 实验 前半部分是理论介绍,后半部分是代码实践,可以选择性阅读。 决策树(decision tree)是功能强大而且相当受欢迎的分类和预估方法&…...
Spring三级缓存学习
Spring的三级缓存机制主要用于解决单例Bean的循环依赖问题。其核心在于提前暴露Bean的引用,允许未完全初始化的对象被其他Bean引用。以下是三级缓存的详细说明及其解决循环依赖的原理: 三级缓存结构 一级缓存(singletonObjects) 存…...
欧拉函数φ
函数作用 计算 1 1 1 ~ n n n中有多少个与 n n n互质的数。 函数公式 φ ( n ) n p 1 − 1 p 1 p 2 − 1 p 2 … … p m − 1 p m φ(n)n\times\frac{p_1-1}{p_1}\times\frac{p_2-1}{p_2}\times……\times\frac{p_m-1}{p_m} φ(n)np1p1−1p2p2−1……pmp…...
蓝桥杯刷题指南
蓝桥杯是中国普及性最好的计算机程序设计竞赛之一,参加者包括大学生、高中生和草根程序员等各个群体。通过刷题来提升自己的编程能力是参加蓝桥杯比赛的常见做法。下面是一些蓝桥杯常见的题型和刷题技巧,希望对大家有所帮助。 基础入门题目:…...
ctfshow WEB web12
发现只有这样一句话,应该是要看页面源代码的,右键查看页面源代码 发现可能存在代码执行漏洞,拼接一个?cmdphpinfo(); 成功显示出php信息, 说明存在代码执行漏洞 接下来遍历目录,我们要用到一个函数 glob() glob() 函数可以查找…...
ChromeOS 135 版本更新
ChromeOS 135 版本更新 一、ChromeOS 135 更新内容 1. ChromeOS 电池寿命优化策略 为了延长 Chromebook 的使用寿命,ChromeOS 135 引入了一项全新的电池充电限制策略 —— DevicePowerBatteryChargingOptimization,可提供更多充电优化选项,…...
redis的缓存
redis的缓存 一.缓存简介1.缓存2.redis作为数据库(MySQL)缓存的原因 二.缓存更新策略1.定期生成2.实时生成3.内存淘汰策略1)FIFO(First In First Out) 先进先出2)LRU(Least Recently Used)淘汰最久未使用的3)LFU(Least…...
字符串与相应函数(上)
字符串处理函数分类 求字符串长度:strlen长度不受限制的字符串函数:strcpy,strcat,strcmp长度受限制的字符串函数:strncpy,strncat,strncmp字符串查找:strstr,strtok错误信息报告:strerror字符操作,内存操作函数&…...
【微知】Mellanox网卡网线插入后驱动的几个日志?(Cable plugged;IPv6 ... link becomes ready)
概要 本文是一个简单的信息记录。记录的是当服务器网卡的光模块插入后内核的日志打印。通过这种日志打印,可以在定位分析问题的时候,知道进行过一次模块插拔。 日志 截图版: 文字版: [32704.121294] mlx5_core 0000:01:00.0…...
spring security oauth2.0的四种模式
OAuth 2.0 定义了 4 种授权模式(Grant Type),用于不同场景下的令牌获取。以下是每种模式的详细说明、适用场景和对比: 一、授权码模式(Authorization Code Grant) 适用场景 • Web 应用(有后端…...
MyBatis-Plus 核心功能
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、条件构造器1、核心 Wrapper 类型基础查询示例SQL 查询使用 QueryWrapper 实现查询 更新操作示例场景一:基础更新SQL 查询使用 QueryWrapper 实现更新…...
阿里云实时计算Flink版产品体验测评
阿里云实时计算Flink版产品体验测评 什么是阿里云实时计算Flink应用场景实时计算Flink&自建Flink集群性价比开发效率运维管理企业安全 场景落地 什么是阿里云实时计算Flink 实时计算Flink大家可能并不陌生,在实时数据处理上,可能会有所接触…...
少儿编程 scratch四级真题 2025年3月电子学会图形化编程等级考试Scratch四级真题解析(判断题)
2025年3月scratch编程等级考试四级真题 判断题(共10题,每题2分,共20分) 11、小圆点角色的程序如下左图所示,程序运行后的效果如下右图所示,自制积木中又调用了自己,这种算法叫做递归。 答案&a…...
【连载3】基础智能体的进展与挑战综述
基础智能体的进展与挑战综述 从类脑智能到具备可进化性、协作性和安全性的系统 【翻译团队】刘军(liujunbupt.edu.cn) 钱雨欣玥 冯梓哲 李正博 李冠谕 朱宇晗 张霄天 孙大壮 黄若溪 2. 认知 人类认知是一种复杂的信息处理系统,它通过多个专门的神经回路协调运行…...
Schaefer 400图谱
图谱下载: https://github.com/ThomasYeoLab/CBIG/tree/master/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal/Parcellations/MNI 图 (第一行)显示了 Yeo et al. (2011) 的 7 网络和 17 网络分包。图…...
通过uri获取文件路径手机适配
青铜版本 return contentResolver.query(this, arrayOf(MediaStore.MediaColumns.DATA), null, null).let {if (it?.moveToFirst() true) {val columnIndex it.getColumnIndex(MediaStore.MediaColumns.DATA)val path it.getString(columnIndex)it.close()return path}&quo…...
Ubuntu 22.04 完美安装 ABAQUS 教程:从零到上手,解决兼容问题
教程概述与安装准备 本教程详细介绍了在 Ubuntu 22.04 系统上安装 ABAQUS 2023 及 ifort 2021 的步骤,并实现用户子程序的链接。教程同样适用于 ABAQUS 2021(需相应调整文件名和路径)以及 Ubuntu 18.04 至 22.04 系统,尽管未在所有版本上测试。需要注意的是,Intel 的 One…...
雷池WAF防火墙如何构筑DDoS防护矩阵?——解读智能语义解析对抗新型流量攻击
本文深度解析雷池WAF防火墙在DDoS攻防中的技术突破,通过智能语义解析、动态基线建模、协同防护体系三大核心技术,实现从流量特征识别到攻击意图预判的进化。结合2023年金融行业混合攻击防御案例,揭示新一代WAF如何通过协议级漏洞预判与AI行为…...
Linux权限理解
1.shell命令以及运行原理 下面来介绍一个话题,关于指令的运行原理,这里先简单理解就可以。当我们登上Linux后: yxx这里称之为用户名,VM-8-2-centos是主机名,~是当前目录,$是命令行提示符。 其中我们把上面的…...
使用labelme进行实例分割标注
前言 最近在学习实例分割算法,参考b站视频课教程,使用labelme标注数据集,在csdn找到相关教程进行数据集格式转换,按照相关目标检测网络对数据集格式的训练要求划分数据集。 1.使用labelme标注图片 在网上随便找了几张蘑菇图片&am…...
策略模式实现 Bean 注入时怎么知道具体注入的是哪个 Bean?
Autowire Resource 的区别 1.来源不同:其中 Autowire 是 Spring2.5 定义的注解,而 Resource 是 Java 定义的注解 2.依赖查找的顺序不同: 依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当…...
PromptUp 网站介绍:AI助力,轻松创作
1. 网站定位与核心功能 promptup.net 可能是一个面向 创作者、设计师、营销人员及艺术爱好者 的AI辅助创作平台,主打 零门槛、智能化的内容生成与优化。其核心功能可能包括: AI艺术创作:通过输入关键词、选择主题或拖放模板,快速生成风格多样的数字艺术作品(如插画、海报…...
软件架构评估利器:质量效用树全解析
质量效用树是软件架构评估中的一种重要工具,它有助于系统地分析和评估软件架构在满足各种质量属性方面的表现。以下是关于质量效用树的详细介绍: 一、定义与作用 质量效用树是一种以树形结构来表示软件质量属性及其相关效用的模型。它将软件的质量目标…...
XILINX DDR3专题---(1)IP核时钟框架介绍
1.什么是Reference Clock,这个时钟一定是200MHz吗? 2.为什么APP_DATA是128bit,怎么算出来的? 3.APP :MEM的比值一定是1:4吗? 4.NO BUFFER是什么意思? 5.什么情况下Reference Clock的时钟源可…...
ubuntu 2204 安装 vcs 2018
安装评估 系统 : Ubuntu 22.04.1 LTS 磁盘 : ubuntu 自身占用了 9.9G , 按照如下步骤 安装后 , 安装后的软件 占用 13.1G 仓库 : 由于安装 libpng12-0 , 添加了一个仓库 安装包 : 安装了多个包(lsb及其依赖包 libpng12-0)安装步骤 参考 ubuntu2018 安装 vcs2018 安装该…...
Python与去中心化存储:从理论到实战的全景指南【无标题】
Python与去中心化存储:从理论到实战的全景指南 随着区块链技术和Web3理念的兴起,去中心化存储逐渐成为构建新型互联网的核心模块之一。传统中心化存储的模式存在易被攻击、单点故障和高昂成本等问题,而去中心化存储通过分布式架构实现了更高的安全性、可靠性和数据透明度。…...
C++语言程序设计——01 C++程序基本结构
目录 编程语言一、C程序执行过程二、C基础框架三、输出语句cout换行 四、注释方法 编程语言 我们知道c是一门编程语言,它是在c语言的基础上发展而来,添加了类、对象、继承、多态等概念,我们可以称为它是一种面向对象编程的语言。 不过在学习…...
Unity UI中的Pixels Per Unit
Pixels Per Unit在图片导入到Unity的时候,将图片格式设置为Sprite的情况下会出现,其意思是精灵中的多少像素对应世界中的一个单位,默认是100 1. 对于在世界坐标中 在世界坐标中,一般对于Sprite的应用是Sprite Renderer组件 使…...
(十八)安卓开发中的后端接口调用详讲解
在安卓开发中,后端接口调用是连接移动应用与服务器的重要环节,用于实现数据的获取、提交和处理。本文将详细讲解安卓开发中后端接口调用的步骤,结合代码示例和具体的使用场景,帮助你全面理解这一过程。 什么是后端接口?…...
使用freebsd-update 升级FreeBSD从FreeBSD 14.1-RELEASE-p5到FreeBSD 14.2-RELEASE
使用freebsd-update 升级FreeBSD从FreeBSD 14.1-RELEASE-p5到FreeBSD 14.2-RELEASE 先升级小版本 准备升级前,先把当前的小版本升级到顶,比如现在是FreeBSD 14.1-RELEASE-p5,先升级到最新的14.1版本,使用命令: # fr…...
基础排序算法(三傻排序)
1. 选择排序 原理:每次从未排序部分选出最小(或最大)元素,放到已排序部分的末尾。时间复杂度:O(n),效率低但实现简单,适合小规模数据。 //选择排序public static void selectSort(int[] arr){i…...
五分钟了解智能体
在2025年人工智能技术全面渗透社会的背景下,“智能体”(Agent)已成为推动第四次工业革命的核心概念之一。从自动驾驶汽车到医疗诊断系统,从智能家居中枢到金融量化交易平台,智能体正在重构人类与技术交互的方式。本文将…...
【机器学习】笔记| 通俗易懂讲解:生成模型和判别模型|01
博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: Yaoyao2024往期回顾:【科研小白系列】这些基础linux命令,你都掌握了嘛?每日一言🌼: “脑袋想不明白的,就用脚想”—…...
Jieba分词的原理及应用(三)
前言 “结巴”中文分词:做最好的 Python 中文分词组件 上一篇文章讲了使用TF-IDF分类器范式进行企业级文本分类的案例。其中提到了中文场景不比英文场景,在喂给模型之前需要进行分词操作。 分词的手段有很多,其中最常用的手段还是Jieba库进行…...
神经网络背后的数学原理
神经网络背后的数学原理 数学建模神经网络数学原理 数学建模 标题民科味道满满。其实这篇小短文就是自我娱乐。 物理世界是物种多样,千姿百态。可以从不同的看待眼中的世界,包括音乐、绘画、舞蹈、雕塑等各种艺术形式。但这些主观的呈现虽然在各人眼中…...
常用图像滤波及色彩调节操作(Opencv)
1. 常用滤波/模糊操作 import cv2 import numpy as np import matplotlib.pyplot as plotimg cv2.imread("tmp.jpg") img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_g cv2.GaussianBlur(img, (7,7), 0) img_mb cv2.medianBlur(img, ksize7) #中指滤波 img_bm …...
FFMPEG和opencv的编译
首先 sudo apt-get update -qq && sudo apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libgnutls28-dev libmp3lame-dev libsdl2-dev libtool libva-dev libvdpau-dev libvorbis-de…...
用户登录不上linux服务器
一般出现这种问题,重新用root用户修改lsy用户的密码即可登录,但是当修改了还是登录不了的时候,去修改一个文件用root才能修改, 然后在最后添加上改用户的名字,例如 原本是只有user的,现在我加上了lsy了&a…...
【项目管理】第11章 项目成本管理-- 知识点整理
相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应:第6章-第19章 (二)知识笔记 第11章 项目成本管理 1.管理基础…...
Python中的strip()
文章目录 基本语法:示例:1. 默认移除空白字符:2. 移除指定字符:3. 不修改原字符串: 相关方法:示例: 注意事项: 在 Python 中, strip() 是一个字符串方法,用于…...
设计模式 Day 9:命令模式(Command Pattern)完整讲解与实战应用
🔄 回顾 Day 8:策略模式 在 Day 8 中我们讲解了策略模式: 用于封装多个可切换的算法逻辑,让调用者在运行时选择合适的策略。它强调的是“行为选择”,是针对“算法或行为差异”而设计。通过 PaymentStrategy、路径规划…...
【正点原子】STM32MP257 同构多核架构下的 ADC 电压采集与处理应用开发实战
在嵌入式系统中,ADC模拟电压的读取是常见的需求。如何高效、并发、且可控地完成数据采集与处理?本篇文章通过双线程分别绑定在 Linux 系统的不同 CPU 核心上,采集 /sys/bus/iio 接口的 ADC 原始值与缩放系数 scale,并在另一个核上…...
区块链从专家到小白
文章目录 含义应用场景典型特征 含义 以非对称加密算法为基础。 每个**区块(Block)**包含: 交易数据(如转账记录、合约内容)。 时间戳(记录生成时间)。 哈希值(当前区…...
记录centos8安装宝塔过程(两个脚本)
1、切换系统源(方便使用宝塔安装脚本下载) bash <(curl -sSL https://linuxmirrors.cn/main.sh) 2、宝塔安装脚本在宝塔的官网 宝塔面板下载,免费全能的服务器运维软件 根据自己的系统选择相应的脚本 urlhttps://download.bt.cn/insta…...
DAY 42 leetcode 151--哈希表.反转字符串中的单词
题号151 给你一个字符串 s ,请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 我的解法 暴力解法,先将String转为字…...
[VTK] 四元素实现旋转平移
VTK 实现旋转,有四元数的方案,也有 vtkTransform 的方案;主要示例代码如下: //构造旋转四元数vtkQuaterniond rotation;rotation.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(90.0),0.0, 1.0, 0.0);//构造旋转点四元数v…...
AI大模型:(二)2.2 分词器Tokenizer
目录 1.分词技术的发展 2.分词器原理 2.1.基于词分词 2.2.基于字符分词 2.3.基于子词分词 3.手搓Byte-Pair Encoding (BPE)分词及训练 3.1.Byte-Pair Encoding (BPE)分词原理 3.2.手搓Byte-Pair Encoding (BPE)分词器 4.如何选择已有的分词器 1. 常见子词分词器及特点…...
codeforces A. Simple Palindrome
目录 题面 代码 题面 A. 简单回文串 每个测试用例时间限制:1 秒 每个测试用例内存限制:256 兆字节 纳雷克要在幼儿园陪一些两岁的孩子度过两个小时。他想教孩子们竞技编程,他们的第一堂课是关于回文串的。 纳雷克发现孩子们只认识英文字母…...