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

Linux中输入和输出基本过程

1.文件内核级缓冲区

前面在如何理解Linux一切皆文件的特点中提到为了保证在Linux中所有进程访问文件时的方式趋近相 同,在f ile 结构体中存在一个 files_operations 结构体指针,对应的结构体保存所有文件操作的函 数指针(这个结构体也被称为操作表)

每一个f ile 结构体中除了有自己的操作表以外还有一个文件的内核级缓冲区,这个缓冲区不同于语言层 面的缓冲区,在调用底层系统接口的读或者写时,会有一方先将内容保存到该缓冲区,再将内容移动到 指定设备

例如,对于读函数 read 来说,以从磁盘文件读取文件内容为例,首先操作系统会从磁盘中读取文件内容 到缓冲区,再由 read 函数从缓冲区将内容读取到指定的设备;对于 将内存中需要写入的内容先写入缓冲区,再由 write 函数来说,首先操作系统会 write 函数从缓冲区写入到磁盘中。除了前面提到的两个 单一过程外,还要一种复合过程:对文件的内容进行修改。这一种过程既涉及到读取,也涉及到写入, 所以首先需要通过操作系统读入需要修改的内容到内核级缓冲区,由 read 函数将缓冲区中的数据读到内 存,在程序运行中对读取到的内容进行修改,再通过 write 函数将修改后的内容写入到缓冲区,最后由 操作系统从缓冲区写入到磁盘

如果抽象化一下 read 函数和 write 函数的过程可以发现这两个函数的基本行为就是读写缓冲区,所以 这两个函数也可以理解为拷贝函数, read 函数即为将缓冲区中的数据拷贝到内存中的指定位置, write 函数即为将内存中的数据拷贝到缓冲区

上面整个过程中, read 函数和 write 函数只完成对缓冲区中的数据进行处理,但是缓冲区中的数据何 时移动到指定的设备由操作系统自主决定

如果用户向自主决定何时将内核级缓冲区中的数据刷新到内核级缓冲区可以使用 fsync函数,其原型如下:

int fsync(int fd);

读或者写过程示意图如下:

2.何为重定向

前面提到,文件描述符是Linux中每一个文件的唯一标识符,也就是说,通过文件描述符可以唯一确定一 个文件,而stdin、stdout和stderr是每一个C语言程序默认打开的三个文件,对应的文件描述符 为0、1和2,而之所以文件描述符是从0开始,本质是因为文件描述符是fd_array数组的下标,当用户 再打开一个文件时,对应的文件结构指针就会存储到fd_array的指定位置,而因为下标0、1和2已经被 占用,所以新开的文件对应的下标只能从3开始

现在关闭0号位置的文件,观察效果,例如下面的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{close(0);int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT);printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

如果关闭的是2号文件,观察效果,例如下面的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{close(2);int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT);printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

运行:

从上面的代码中可以看出,在Linux中,一个文件被打开时,文件描述符的分配原则是在 fd_array 中找 到最小的且没有被其他 file 结构指针占用的位置

以关闭0号位置为例,示意图如下:

在上面的演示中,先关闭了某一个文件描述符较前的文件,再打开另一个文件,打开的这个文件所处的 位置是就是被关闭的那个文件的位置,此时再使用输出语句输出内容,原本应该输出到文件描述符较前 的原始文件中,比如前面的 stdin ,后面却输出到了文件中 test1.txt ,这个过程就称为文件重定 向,主要原理就是文件描述符是固定不变的,而输出和输入只认文件描述符,不会在意这个文件描述符 对应的位置指向的是哪一个文件

在Linux中,存在一个系统调用接口使得可以在程序中实现重定向,这个函数为dup2,其原型如下:

int dup2(int oldfd, int newfd);

在Linux操作手册中, dup2 函数的描述如下:

dup2() makes newfd be the copy of oldfd, closing newfd first if necessary

参数解释:

  1. oldfd:该参数表示待拷贝的文件的文件指针对应的文件描述符
  2. newfd:该参数表示被覆盖的文件的文件指针对应的文件描述符

示意图如下:

所以,使用dup2就可以实现使用printf函数本应该输出到stdout中,而输出到test1.txt的效 果,代码如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);dup2(fd1, 1);printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

需要注意,因为在使用 dup2 函数之前, stdout 已经被打开了,此时 open 函数打开 时就只能使用3号下标的位置,所以可以看到 test1.txt 文件 dup2 函数的确实现了将内容输出到 test1.txt 文件而不 是st dout 中,此时示意图如下:

这里需要注意一个细节:尽管 dup2 函数会关闭被覆盖的文件 test1.txt 占用了被覆盖的文件 stdout ,但是关闭后被拷贝的文件 stdout 的位置,所以再打开其他文件依旧会从7号位置开始,例如下 面的代码演示:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);dup2(fd1, 1);int fd5 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666); // 重定向后打开一个新文件printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);printf("%d\n", fd5);close(fd1);close(fd2);close(fd3);close(fd4);close(fd5);return 0;
}

但是,前面的代码中,只演示了关闭0号位置和2号位置的文件,如果此时关闭1号位置的文件,再打开同 样的四个文件,输出每一个文件的文件描述符,从前面的规律可以推出,输出语句会因为1号位置的文件 是test1.txt而将内容输出到test1.txt中,例如下面的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{close(1);int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

编译运行上面的代码后可以看到不论是test1.txt还是其他文件都没有显示需要的内容,控制台也没有 正常打印需要的内容

但是如果将代码修改为如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{// ...fflush(stdout);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

编译运行上面的代码后可以看到结果如下:

现在就引入了一个问题,为什么加了fflush(stdout)就可以看到需要的效果

前面提到,在调用操作系统接口中的读写函数时会涉及到一个文件内核级缓冲区,这个缓冲区是为了减 少操作系统进行IO操作时产生的时间和空间的消耗,但是如果用户使用的是语言级别的接口,例如 fread或者fwrite等,那么此时就会出现用户的接口到操作系统的消耗,这个消耗主要来自于语言级 函数多次调用系统接口时创建函数栈帧,所以为了减少这种情况下的时间和空间消耗,就存在了语言级 别的缓冲区

但是,在实现进度条时提到了\n可以刷新语言级别的缓冲区,此处为什么用了\n也没有刷新,原因就 在于语言级别的缓冲区刷新情况有三种:

  1. 行刷新,主要是stdout文件时的刷新
  2. 满刷新,当语言级别的缓冲区写满时刷新
  3. 不缓冲

而此处的\n就属于行刷新,但是此时的printf认识的fd为1的文件并不是stdout,所以行刷新就 失效了,转换成默认的满刷新,所以需要调用fflush(stdout)将当前语言级别缓冲区中的数据调用写 函数刷新到操作系统的内核级缓冲区,再由操作系统自主刷新到输出设备中

如果将前面的代码修改为如下,观察效果:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{close(1);int fd1 = open("test1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd2 = open("test2.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd3 = open("test3.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);int fd4 = open("test4.txt", O_WRONLY | O_TRUNC | O_CREAT, 0666);printf("%d\n", fd1);printf("%d\n", fd2);printf("%d\n", fd3);printf("%d\n", fd4);return 0;
}

编译运行上面的代码后可以看到结果如下:

可以看到此时尽管没有fflush(stdout)也可以正常将内容输出到test1.txt,主要原因是当程序即 将结束时,会进行缓冲区自动刷新,相当于自动进行了一次fflush(stdout),而前面调用 close(fd)时之所以没有刷新缓冲区是因为系统内部的文件已经被关闭,语言级的缓冲区无法将内容通 过系统调用刷新到系统内核级缓冲区

所以,由上面的结果可以推出,在C语言中,文件结构FILE肯定包含文件描述符和缓冲区,而C语言的 所有输入输出函数本质也是拷贝函数,只是源头或者目标是其结构体中的缓冲区,对应的源码如下:

struct _IO_FILE {int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags//缓冲区相关/* The following pointers correspond to the C++ streambuf protocol. *//* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */char* _IO_write_base; /* Start of put area. */char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. *//* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */struct _IO_marker *_markers;struct _IO_FILE *_chain;int _fileno; //封装的文件描述符#if 0int _blksize;
#elseint _flags2;
#endif_IO_off_t _old_offset; /* This used to be _offset but it's too small. */
#define __HAVE_COLUMN /* temporary *//* 1+column number of pbase(); 0 is unknown. */ unsigned short _cur_column; signed char _vtable_offset; char _shortbuf[1];/* char* _save_gptr; char* _save_egptr; */_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

3.子进程与缓冲区

前面演示的都是只有一个进程打开关闭文件,如果此时在自动刷新语言级别的缓冲区之前创建了一个子 进程,观察下面代码的执行效果:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int fd = open("log.txt", O_CREAT | O_WRONLY | O_APPEND, 0666);dup2(fd, stdout->_fileno);// C库函数printf(" hello printf\n");fprintf(stdout, " hello fprintf\n");const char *message = " hello fwrite\n";fwrite(message, 1, strlen(message), stdout);// 系统调用const char *w = " hello write\n";write(1, w, strlen(w));// 创建子进程fork();return 0;
}

查看 log.txt 的内容

可以看到,除了系统调用接口 write 函数以外,其他的C语言库函数均出现两次打印的情况,本质就是 因为语言级缓冲区自动刷新到系统内核级缓冲区机制,而因为 fork 创建了子进程,所以子进程在不修改 的情况下会共享父进程中的所有内容,包括语言级缓冲区,所以在最后程序结束时,因为父进程没有刷 新语言级缓冲区,所以创建子进程之后,父子进程都要进行一次刷新操作,所以父子进程都通过系统调 用接口将数据写入到内核级缓冲区中,而之所以 write 函数没有写入两次,就是因为父进程已经调用完 成write函数了,系统内核级缓冲区已经有对应的内容,所以此时子进程就不需要再调用了,最后由操 作系统决定将所有内容刷新到文件中

相关文章:

Linux中输入和输出基本过程

1.文件内核级缓冲区 前面在如何理解Linux一切皆文件的特点中提到为了保证在Linux中所有进程访问文件时的方式趋近相 同&#xff0c;在f ile 结构体中存在一个 files_operations 结构体指针&#xff0c;对应的结构体保存所有文件操作的函 数指针&#xff08;这个结构体也被称为…...

二、FIFO缓存

FIFO缓存 1.FIFO缓存介绍2.FIFO缓存实现3.FIFO缓存总结 1.FIFO缓存介绍 FIFO&#xff08;First-In-First-Out&#xff09;缓存 是一种简单的缓存淘汰策略&#xff0c;它基于先进先出的原则来管理数据。当缓存达到容量限制并需要淘汰元素时&#xff0c;最先进入缓存的元素会被移…...

Linux_挂载nas

1、安装挂载nas必要的服务 yum -y install nfs-utils rpcbind 2、挂载nas sudo mount -t nfs -o vers3,nolock,prototcp,noresvport <NAS-IP>:/path/to/shared /yourNasPath mount 命令详解&#xff1a; -t &#xff1a;文件系统类型 &#xff0c;这里指定的挂载类…...

uni-app开发AI康复锻炼小程序,帮助肢体受伤患者康复!

**提要&#xff1a;**近段时间我们收到多个康复机构用户&#xff0c;咨询AI运动识别插件是否可以应用于肢力运动受限患者的康复锻炼中来&#xff0c;插件是可以应用到AI康复锻炼中的&#xff0c;今天小编就为您介绍一下AI运动识别插件在康腹锻炼中的应用场景。 一、康复机构的应…...

现代密码学总结(上篇)

现代密码学总结 &#xff08;v.1.0.0版本&#xff09;之后会更新内容 基本说明&#xff1a; ∙ \bullet ∙如果 A A A是随机算法&#xff0c; y ← A ( x ) y\leftarrow A(x) y←A(x)表示输入为 x x x ,通过均匀选择 的随机带运行 A A A,并且将输出赋给 y y y。 ∙ \bullet …...

按照字幕拆解视频实战

1. 基本实现思路 字幕文件处理&#xff1a; 提取字幕内容和时间戳&#xff08;如 SRT 文件格式&#xff09;。解析字幕中的开始时间和结束时间。 视频切割&#xff1a; 使用字幕的时间戳&#xff0c;剪辑对应时间段的视频。每段字幕对应一个子视频。 输出子视频&#xff1a; …...

2.11.静态链表

一.静态链表的基本概念&#xff1a; 1.上图说明&#xff1a;索引为0处是头结点&#xff0c;头结点不存储数据&#xff0c;但存储下一个结点的数组下标&#xff0c;本例中头结点里存储的下一个结点的数组下标为2&#xff0c;即索引为2的结点为头结点后的第一个结点&#xff0c;以…...

分页查询在数据库中的好处

分页查询在数据库中的好处主要体现在以下几个方面&#xff1a; 提高性能&#xff1a; 减少数据传输&#xff1a;分页查询只返回请求的页面数据&#xff0c;而不是整个数据集&#xff0c;这减少了网络传输的数据量&#xff0c;降低了网络延迟和带宽消耗。减少内存使用&#xff1…...

电子应用设计方案-54:智能AI人工智能机器人系统方案设计

智能 AI 人工智能机器人系统方案设计 一、引言 随着人工智能技术的快速发展&#xff0c;智能 AI 机器人在各个领域的应用越来越广泛。本方案旨在设计一个功能强大、智能高效、交互友好的人工智能机器人系统&#xff0c;以满足不同场景下的用户需求。 二、系统概述 1. 系统目标…...

μC/OS-Ⅱ源码学习(6)---事件标志组

快速回顾 μC/OS-Ⅱ中的多任务 μC/OS-Ⅱ源码学习(1)---多任务系统的实现 μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下) μC/OS-Ⅱ源码学习(3)---事件模型 μC/OS-Ⅱ源码学习(4)---信号量 μC/OS-Ⅱ源码学习(5)---消息队列 本文进一步解析事件模型中&#xff0c;事件标志…...

ASP.NET|日常开发中读写TXT文本详解

ASP.NET&#xff5c;日常开发中读写TXT文本详解 前言一、读取 TXT 文本1.1 使用StreamReader类 二、写入 TXT 文本2.1 使用StreamWriter类 三、文件编码问题3.1 常见编码格式 四、错误处理和性能考虑4.1 错误处理4.2 性能考虑 结束语优质源码分享 ASP.NET&#xff5c;日常开发中…...

《C 语言向量运算:点亮人工智能几何计算之路》

在人工智能蓬勃发展的时代&#xff0c;数学运算作为其坚实的基石发挥着不可替代的作用。而向量的点积与叉积运算&#xff0c;更是在人工智能的几何计算领域有着独特且关键的地位。今天&#xff0c;就让我们一同深入探讨如何在 C 语言中实现向量的点积、叉积运算&#xff0c;并领…...

HarmonyOS 获取进程相关的信息process 常用的几个方法

获取进程相关的信息&#xff0c;提供进程管理的相关功能。 process 1. EventListener 2. isIsolatedProcess 3. is64Bit 4. getStartRealtime 5. getPastCpuTime 导入模块 import { process } from kit.ArkTS; 属性 名称类型可读可写说明uidnumber是否进程的用户标识。…...

Linux 权限管理实践:精确控制用户对 systemctl 和 journalctl 命令的使用

前言 在 Linux 系统管理中&#xff0c;精确控制用户对特定命令的访问权限是一项关键的安全实践。使用 systemctl 和 journalctl 命令时&#xff0c;不当的权限设置可能会导致不必要的风险。本篇博客将详细讨论如何通过 sudoers 文件和 Polkit 策略为不同用户配置 systemctl 和…...

图像处理之滤波

中值滤波、均值滤波、高斯滤波和双边滤波是常见的图像处理技术&#xff0c;主要用于去噪和图像平滑。低通滤波和高通滤波用于处理图像中的频率成分。它们的主要区别在于它们所允许通过的频率范围。滤波、卷积、去噪、模糊、提取特征是一个意思。 卷积就是两个矩阵的乘法&#…...

html基础-认识html

1.什么是html html是浏览器可以识别的的标记语言&#xff0c;我们在浏览器浏览的网页就是一个个的html文档 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>认识html</title> </head> <body><h1…...

金智塔科技联合浙大人工智能研究所发布全新“智信”可信行业数据空间,共促数字金融创新发展!

由中国计算机学会(CCF)主办&#xff0c;CCF数字金融分会、同济大学、上海立信会计金融学院联合承办&#xff0c;金智塔科技作为金牌合作单位的数字金融领域年度巅峰盛会——首届CCF中国数字金融大会于2024年12月7日在上海成功举办。中国工程院院士蒋昌俊任大会主席&#xff0c;…...

基于单片机的语音识别自动避障小车(论文+源码)

1.系统设计 此次基于单片机的语音识别自动避障小车&#xff0c;以STC89C52单片机作为系统的主控制器&#xff0c;利用超声波模块来实现小车与障碍物距离的测量并通过LCD液晶显示&#xff0c;当距离低于阈值时会通过WT588语音模块进行报警提示&#xff0c;并且小车会后退来躲避…...

使用layui的table提示Could not parse as expression(踩坑记录)

踩坑记录 报错图如下 原因&#xff1a; 原来代码是下图这样 上下俩中括号都是连在一起的&#xff0c;可能导致解析问题 改成如下图这样 重新启动项目&#xff0c;运行正常&#xff01;...

EF Code 多对多表关系建设和Linq 知识点

自引用组织结构树&#xff0c;比如部门、组织 除了根节点&#xff0c;其他节点都有一个父节点&#xff0c;也包含多个子节点&#xff0c;那么在定义表结构时&#xff0c;既要申明父表的关系&#xff0c;也要申明子表的关系 EF Code 多对多 builder.ToTable("T_Student&…...

Maven 的下载

目录 1、Maven 官方地址2、下载3、解压4、配置本地仓库 1、Maven 官方地址 https://maven.apache.org/ 2、下载 3、解压 将下载的压缩包解压到任意位置 4、配置本地仓库 在 Maven 的安装目录下新建文件夹&#xff0c;用来当作 Maven 的本地仓库 进入 conf 目录下&#xff…...

VPN模式

拓扑结构 实验图&#xff1a; 路由器router 配置 DHCP配置 需要右键激活 路由器项配置网关 dns项配置ip DNS服务配置 正向区域 选择不允许动态更新 反向区域 创建主机 正向 验证是否创建成功 反向查找区域 输入网段 使用默认名称---不允许动态更新 KALI机的验证 web服务…...

LeetCode 热题 100-两数之和(简单)

1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值 target 的那两个整数&#xff0c;并返回它们的数组下标。你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。…...

【C语言】拆解C语言的编译过程

前言 学习C语言的过程中&#xff0c;涉及到各种各样的关键词&#xff0c;在我们点击编译的时候&#xff0c;都会做什么呢&#xff1f;让我们来拆解一下 C语言的编译过程 C语言的编译过程包括预处理、编译、汇编和链接四个主要步骤。每个步骤都有其特定的任务和输出文件类型&am…...

RabbitMQ中的Work Queues模式

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信和解耦系统的关键组件之一。RabbitMQ 是一个广泛使用的开源消息代理软件&#xff0c;支持多种消息传递模式。其中&#xff0c;Work Queues&#xff08;工作队列&#xff09;模式是一…...

OpenCV圆形标定板检测算法findGrid原理详解

OpenCV的findGrid函数检测圆形标定板的流程如下: class CirclesGridClusterFinder {CirclesGridClusterFinder(const CirclesGridClusterFinder&); public:CirclesGridClusterFinder...

快速理解类的加载过程

当程序主动使用某个类时&#xff0c;如果该类还未加载到内存中&#xff0c;则系统会通过如下三个步骤来对该类进行初始化&#xff1a; 1.加载&#xff1a;将class文件字节码内容加载到内存中&#xff0c;并将这些静态数据转换成方法区的运行时数据结构&#xff0c;然后生成一个…...

monorepo代码管理框架

1. 新建 vue3-component 文件夹 2. 运行pnpm init 3. pnpm i vue typescript 4. 新建.npmrc shamefully-hoisttrue link-workspace-packagestrue 5. ts文件配置 pnpm tsc --init 默认.bin路径下的tsc 6. 新建pnpm-workspace.yaml packages:- packages/** # all packages- p…...

LabVIEW实现蓝牙通信

目录 1、蓝牙通信原理 2、硬件环境部署 3、程序架构 4、前面板设计 5、程序框图设计 6、测试验证 本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合实际案例,展示如何利用LabVIEW和常用模块实现物联网系…...

R环境配置 以及Debug方法 (VSCode, conda, 远程R)

生物信息学中的R环境配置 以及Debug方法 开始设置1、建议使用VSCode conda 远程R2、 VSCode配置安装插件安装好插件后&#xff0c;远程设置链接成功后&#xff0c;设置项目 3、 linux conda 和 远程R配置4、VScode 远程访问R环境下面配置远程R 5、开始Debug新建个R文件&#…...

ComfyUI 与 Stable Diffusion WebUI 的优缺点比较

ComfyUI与Stable Diffusion WebUI都是AI绘画领域比较知名两款产品&#xff0c;两者存在诸多差异&#xff0c;本篇就带你熟悉二者的优劣&#xff0c;方便自己做出决策。 界面与操作 ComfyUI&#xff1a;界面简洁直观&#xff0c;通过节点和连线的方式构建工作流&#xff0c;用…...

Ubuntu 系统下安装 Nginx

一、Nginx是什么 是一个高性能的 HTTP 和反向代理 web 服务器&#xff0c;同时也提供了 IMAP/POP3/SMTP 服务。 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在BSD-like 协议下发行。其特点是占有内存少&…...

【Qt】drawText字体大小问题探究

背景 软件的一个功能是&#xff1a; 打开图片在图片上绘制序号&#xff0c;序号的样式是圆圈内包含数字将带有序号的图片打印出来 实现思路也很简单&#xff0c;在屏幕上显示时重写paintEvent函数&#xff0c;利用QPainter完成图片和序号的绘制。打印时只需要将QPainter对应…...

视频汇聚平台:Liveweb视频流媒体平台视频监控系统解决方案

数字化技术在安防领域的广泛应用已经成为公安等重要执法部门的重要趋势&#xff0c;主要得益于无线网络通信技术和计算机技术的快速进步。传统的视频监控系统存在诸多局限&#xff0c;例如只能进行现场监视&#xff0c;报警信息传输简单&#xff0c;无法远距离传输视频信号&…...

Android开发中有关MediaPlayer 播放.mp3文件使用之一

我们在项目中&#xff0c;经常会添加一个简单的语音提示&#xff1a;我们通常会选择MediaPlayer播放SD文件中的.MP3文件或者存到assets下的.mp3文件。正常使用流程如下&#xff1a; 一、播放assets下的.mp3文件 根据assets获取需要播放的文件名 getApplicationContext().getAs…...

Leetcode经典题11--加油站

题目描述 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和…...

23种设计模式之状态模式

目录 1. 简介2. 代码2.1 State &#xff08;定义抽象状态接口&#xff09;2.2 StartState &#xff08;实现具体状态类&#xff09;2.3 EndState &#xff08;实现具体状态类&#xff09;2.4 Context &#xff08;定义上下文类&#xff09;2.5 Test &#xff08;测试类&#xf…...

大模型的构建与部署(3)——数据标注

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 数据标注的重要性 1.1 增强数据可解释性 数据标注通过为原始数据添加标签或注释,显著增强了数据的可解释性。在机器学习和深度学习领域,模型的训练依赖于大量带标签的数据。这些标签不仅帮助…...

windows11 专业版 docker desktop 安装指南

家庭中文版需升级专业版&#xff0c;家庭版没有hyper-v。 开始运行optionalfeatures.exe打开windows功能 安装wsl2 步骤 1 - 启用适用于 Linux 的 Windows 子系统步骤 2 - 检查运行 WSL 2 的要求步骤 3 - 启用虚拟机功能步骤 4 - 下载 Linux 内核更新包 步骤 1 - 启用适用于 L…...

mixed strategy

混合策略和期望收益的基本概念 在博弈论中&#xff0c;混合策略是指参与者以一定的概率选择不同的纯策略。期望收益则是在考虑这些概率的情况下&#xff0c;参与者所能获得的平均收益。 以“石头 - 剪刀 - 布”游戏为例 游戏规则回顾 石头胜剪刀&#xff0c;剪刀胜布&#xff0…...

登上Nature和CVPR!小波变换+UNet上大分!

最近UNet又出现了不少新成果&#xff0c;结合小波变换屡登Nature子刊和CVPR24&#xff01;比如三路径U-Net模型&#xff0c;利用Haar小波变换大幅提高系统整体性能&#xff1b;再比如利用小波变换的特性来改进U-Net架构的MLWNet网络&#xff0c;性能猛超SOTA&#xff01; 原因…...

2_使用 HTML5 Canvas API (1) --[HTML5 API 学习之旅]

1.在页面中加入 canvas 在网页中加入 <canvas> 元素可以通过简单的 HTML 和 JavaScript 实现。以下是两个具体的示例&#xff0c;展示了如何在页面中使用 <canvas> 绘制图形和处理用户交互。 示例 1: 简单的静态绘图 这个例子展示了一个基础的 <canvas> 应…...

梳理你的思路(从OOP到架构设计)_UML应用:业务内涵的分析抽象表达01

目录 1、 系统分析(System Analysis) 系統分析的涵意 业务(领域)知识 业务内涵 业务(领域)概念 2、举例(一) &#xff1a;东方传说 UML与建模工具 1、 系统分析(System Analysis) 系統分析的涵意 许多人在学习系统分析(System Analysis)时&#xff0c;常迷失于其字面上…...

redis集群安装部署 redis三主三从集群

redis集群安装部署 redis三主三从集群 1、下载redis2、安装redis集群 三主三从3、配置redis开机自启动3.1、建立启动脚本3.2、复制多份redis启动脚本给集群使用3.3、添加可执行权限3.4、配置开机自启动 1、下载redis 本次redis安装部署选择当前最新的稳定版本7.4.1 下载链接: …...

【PHP】部署和发布PHP网站到IIS服务器

欢迎来到《小5讲堂》 这是《PHP》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言安装PHP稳定版本线程安全版解压使用 PHP配置配置文件扩展文件路径…...

大模型qiming面试内容整理-系统设计与架构

在大模型和机器学习相关岗位的面试中,系统设计与架构的考察通常会涉及如何设计一个可扩展、可靠且高效的机器学习系统,特别是在面对大规模数据和复杂模型时。这一部分的考察不仅测试候选人对机器学习和深度学习的理解,还会评估其如何设计实际生产环境中的系统来满足需求。以…...

【Reading Notes】Favorite Articles from 2024

文章目录 1、January2、February3、March4、April5、May6、June7、July8、August9、September10、October11、November12、December 1、January 2、February 3、March Sora外部测试翻车了&#xff01;3个视频都有Bug&#xff08; 2024年03月01日&#xff09; 不仔细看还真看不…...

Qt-chart 画柱状图

记录下&#xff0c;记录下 效果图 直接上代码 // 创建柱状系列 QBarSeries *series new QBarSeries();// 创建数据集 QBarSet *setTar new QBarSet(("tar"));QBarSet *setReality new QBarSet(("reality"));//添加柱状数据*setTar << 1<<…...

【深入理解Java线程池】

深入理解Java线程池 Java线程池是Java并发编程中的一个重要概念&#xff0c;它提供了一种管理和复用线程的机制&#xff0c;可以显著减少创建和销毁线程的开销&#xff0c;提高系统的响应速度和吞吐量。以下是对Java线程池的详细解析&#xff1a; 一、线程池的基本概念 线程…...

honle电源控制器维修UV灯高压电源EVG EPS200

UV电源控制器维修&#xff1b;honle电源维修&#xff1b;UV电源维修MUC-Steuermodul 2 LΛmpen D-82166 主要维修型号&#xff1a; EPS 60/120、EPS 100、EPS200、EPS 220、EPS 340、LED Spot 100、UV2000F HONLE UV灯高压电源控制器故障包括&#xff1a; 1、电压不稳&#…...