【Linux】重定向原理dup2缓冲区

news2024/9/29 13:30:12

文章目录

    • 重定向原理
      • 输出重定向
        • 关于FILE
        • 解释输出重定向原理
      • 追加重定向
      • 输入重定向
    • dup2
  • 缓冲区
      • 语言级别的缓冲区
      • 内核缓冲区

重定向原理

重定向的本质就是修改文件描述符下标对应的struct file*的内容

输出重定向

  • 输出重定向就是把本来应该输出到显示器的数据重定向输出到另一个文件当中

假设我们先关闭1标准输入,然后再打开一个文件,按照文件描述符的分配规则,给再打开文件分配的文件描述符fd就是1,那么是不是把输出的内容打印到屏幕上呢

image-20220701155706525

  • 由此现象,我们也可以看出,printf的底层是往fd=1的文件中打印内容,不关心该文件是什么

此时把本来应该打印到显示器的内容,显示到文件中,这种行为称为输出重定向


为什么是这样实现输出重定向呢?

  • close(1) ->断开了与显示器文件的联系, 相当于把fd_array[1]位置的内容置空
  • 然后再打开新文件log.txt,由文件描述符分配规则,fd_array[1]指向log.txt文件(存放log.txt文件的struct file的地址)

image-20220701160423572


所以C语言中的打印函数–printf,本质是往 标准输出(stdout)打印

image-20220701160557039


关于FILE

stdout和stdin和stderr的类型都是FILE*,是一个文件指针,那FILE到底 是什么呢?

FILE是C语言层面上的结构体

image-20220701161110371

库函数是对系统调用接口的封装,本质是访问文件都是通过文件描述符进行访问的,所以C库函数中的File结构体内部一定封装了文件描述符fd


以C语言的fwite函数为例子:该函数是向文件流中写入内容,然后实际在底层中 是通过文件描述符fd写到磁盘上

image-20220701161236596

所以我们可以推断, C语言的FILE结构体一定包含一个fd, C++中的cin,cout,cerr这些流对象的属性中也一定包含文件描述符fd

struct FILE
{
  //一定包含了一个整数,是对应在系统层面这个新打开文件的fd  
};

所以:语言上的in/out/err和系统上的012存在联系

  • stdin 标准输入,键盘 -> 包含fd = 1
  • stdout 标准输出,显示器 -> 包含fd = 2
  • stderr 标准输出,显示器 -> 包含fd = 3

我们可以在内核中看一下FILE的定义:

  • 其中的_filno就是文件描述符
//在/usr/include/libio.h
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 0
 int _blksize;
#else
 int _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
};

stdout,stderr,stdin都是结构体FILE指针,所以我们可以把其指向的文件描述符打印出来:

image-20220701163305219


知道了FILE里面封装了文件描述符fd之后,我们可以理解一下C库函数fopen究竟在做什么

FILE *fopen(const char *path, const char *mode)

fopen函数在上层为用户申请一个FILE结构体变量,并返回该结构体的地址(FILE*), 在底层通过系统调用接口open打开对应的文件,得到文件描述符fd,并把这个文件描述符fd填充到FILE结构体的 _fileno变量当中,至此便完成了文件打开的工作

而C语言中的其它文件操作函数, 比如fputs,fgets等,都是先根据我们传入的文件指针找到对应的FILE结构体,然后再FILE结构体中找到文件描述符fd,最后通过文件描述符fd找到对应的文件,对文件进行一系列的操作


关于echo的重定向:

image-20220701163429505

把本来输出的显示器的内容输出到文件中, 实际上echo命令也是一个进程, 把echo进程的显示器文件stdout关闭掉(close(1)) , 再把log.txt文件打开,于是给log.txt文件分配的文件描述符就是1, echo实际就是向文件描述符为1的文件输出数据, 不关心文件描述符为1的文件是什么, 现在文件描述符为1的文件是log.txt, 于是输出的内容就被打印到log.txt中


解释输出重定向原理

关闭1, 再打开文件,给该文件分配的文件描述符就是1, printf函数是向stdout中打印,stdout的类型是FILE*类型. FILE是一个结构体,该结构体内部存储文件描述符的遍变量,与系统的1对应,而printf只关心这个整数1,printf实际上就是向文件描述符为1的文件输出数据, 并不关心文件描述符为1下标的文件是什么, 而现在我们1下标指向的是log.txt文件,所以printf就是往log.txt文件中写入


追加重定向

  • 追加重定向和输出重定向的区别:输出重定向是覆盖式的输出数据,会把原来已经有的数据覆盖掉再写进去,而追加重定向是追加式输出数据,在原来已经有的数据基础上写入数据

追加重定向与输出重定向唯一的差别就是在打开方式上,增加了 O_APPEND选项

image-20220701164454634


输入重定向

什么叫输入重定向?

把本来应该从键盘中读取内容改成从文件中读取内容

image-20220701164914837


这里以fgets函数为例子:

image-20220701164713010

从特定的文件流中按行读取内容,内容放在缓冲区s中.读取成功返回字符串的起始地址,否则返回NULL 第二个参数:缓冲区大小

image-20220701165208937

本来应该从标准输入(键盘)中获取数据,现在变成从log.txt文件获取数据

解释:

如果我们想让本应该从键盘文件读数据的scanf函数,改为从log.txt文件读取数据,我们只需要先关闭0描述符对应的文件关闭,也就是将键盘文件关闭, 后续我们打开文件log.txt ,给该文件分配的文件描述符就是0, stdin的类型是FILE*类型. FILE是一个结构体,该结构体中存储的文件描述符就是0,与系统的0对应,因此scanf实际就是向文件描述符为0的文件读取数据 而现在我们0下标指向的是log.txt文件,所就是从log.txt文件中读取数据


dup2

上述我们重定向的方法是:关闭文件然后再打开文件的方式进行重定向,但这个只是特殊情况

而更多的是:

例如:现在有两个文件描述符1 和 3被打开了,如何实现输出重定向呢?

因为在语言层调用接口的时候,函数只认数字1下标, 而不关心1下标指向的文件是什么,所以我们可以

  • 把文件描述符3中的内容拷贝到文件描述符1中,就实现了原来应该向显示器文件写入,现在往文件描述符3对应的文件写入

image-20220701171352333


dup2函数就是干这个事情的!

#include <unistd.h>
int dup2(int oldfd, int newfd);

dup2()  makes  newfd  be the copy of oldfd, closing newfd first if necessary, but note the
    following:
*  If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.
*  If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2()  does nothing, and returns newfd.

函数功能:dup2会把fd_array[oldfd]的内容拷贝到fd_array[newfd]当中,有必要时我们需要先关闭文件描述符为newfd的文件

  • 最终oldfd和newfd都变成oldfd的内容,可以认为把oldfd的内容覆盖原来newfd的内容

函数返回值: 如果函数调用成功,返回newfd,否则返回-1

由上述的翻译可以得出:

  • 1.如果oldfd不是有效的文件描述符,则dup2调用失败,并且此时文件描述符为newfd的文件没有被关闭
  • 2.如果oldfd是一个有效的文件描述符,但是newfd和oldfd是相同的,则dup2不做任何操作,并返回newfd

输出重定向

dup2(fd,1);//oldfd,newfd

我们把打开文件是获得的文件描述符fd和1传入dup2函数,那么dup2会把fd_array[fd]的内容拷贝到fd_array[1]中,我们向stdout输出数据,而stdout是向文件描述符为1的文件输出数据,因此,本来应该输出到显示器的数据就会重定向输出到log.txt文件当中

image-20220701205635827

选项O_TRUNC的含义:清空原来的内容再写入 O_CREAT:要打开的文件不存在就先创建,后面要自定义文件的权限

O_WRONLY : 以写的方式打开文件

  • C语言中文件操作的 "w"选项 也会先把原始文件清空,说明上层封装了这个选项

追加重定向

只需在输出只写O_WRONLY选项的基础上添加O_APPEND选项

image-20220701210004563


输入重定向

dup2(fd,0); //原本从键盘读取内容,现在从文件中读取内容

image-20220701210528921


问:执行exec* 程序替换,会影响我们曾经打开的文件嘛?

不会!因为替换的是代码和数据,并不会影响进程内核的数据结构

例子:

echo "hello Mango" > log.txt

在命令行上的重定向,会进行字符串分析, 发现>重定向符号时,会先执行dup2函数,然后进行程序替换,此时echo的内容就会重定向到指定的文件当中,程序替换并不会替换打开的文件

  • 相当于是: fork创建子进程 -> 子进程执行dup2(fd,1) ->子进程执行程序替换exec*函数

那子进程会不会和父进程共享文件描述符表呢?

会! 子进程也会形成自己的file_strcut结构体,子进程内核的数据结构task_strcut会以父进程为模板初始化自身,因此父进程和子进程的文件描述符表就是一样的,父子指向同一份文件


image-20220701215140215

父进程如果曾经打开了标准输入,标准输出,标准错误,那么子进程也会继承下去

  • 这也是为什么所有的进程都会默认打开标准输入,标准输出,标准错误,就是因为我们命令行上的进程的父进程都是bash, 也就是命令行解释器,bash需要打开标准输入进行输入指令,打开标准输出用于打印结果,打开标准错误用于提示错误信息, 创建子进程的时候,默认也继承下去了, 所以在命令行上启动的子进程最终都打开了这三个东西 (引用计数)

缓冲区

标准输出和标准错误都可以向显示器打印内容,这二者有什么区别呢?

  • 当我们重定向的时候,我们可以发现,只有标准输出的内容进行了重定向, 因为>叫做输出重定向,即把本应该显示到1号文件描述符的内容写入到指定的文件当中,而2号文件描述符并没有发生改变,仍指向标准错误

image-20220701220243345


实际上我们使用重定向时,重定向的是文件描述符为1的标准输出流,并不会对文件描述符为2的标准错误流进行重定向


那如果我们想把标准输出和标准错误的内容都重定向怎么办呢?

./可执行程序 > 文件 2>&1 表示标准错误和标准输出都进行重定向

image-20220701220359511

这样写可以理解为:

先执行前面的语句: 把1本来指向显示器的内容,变成指向特定的文件, 而后面的2>&1指的是:把1里面的内容拷贝到2, 因为1经过重定向了,指向新文件, 所以2也指向新文件

image-20220701221033523


语言级别的缓冲区

刚才我们进行重定向的时候,打开了文件却没有关闭,最后应该close(fd),

没有close(fd)的情况下 和 close(fd)的情况下对比:

image-20220702112128312


我们可以发现: close之后, C语言的写入接口,像printf,fprintf重定向后并没有被刷新出来,这是什么原因呢?


首先我们要知道缓冲区的概念, 我们之前说的缓冲区,都是指语言级别的用户级的缓冲区,也就是由C语言提供的缓冲区

C语言中的printf ,fprintf向标准输出stdout写入的时候,本质都是 写入/拷贝到C语言的缓冲区当中,然后系统会定期的把C语言缓冲区的内容拷贝到内核的缓冲区,OS再把数据更新到硬件上

而C语言缓冲区的内容写入到内核缓冲区当中,相当于把数据写入文件当中, 一定需要 fd

image-20220702113323079


那C语言提供的缓冲区又在哪呢?

前面我们知道FILE结构体当中封装了一个fd ,其实该结构体里面还 维护了与C语言缓冲区相关的内容

我们可以看一下它的源码:它是用指针来表示缓冲区的区间 (和我们vector的模拟实现相似)

//在/usr/include/libio.h
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 0
 int _blksize;
#else
 int _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
};

我们使用stdin/stdout/stderr 和自己打开的文件,拿到的一个文件指针FILE* ,我们的printf和fprintf都是先写到FILE*对应的FILE结构体的文件缓冲区当中, 即暂时存在FILE结构体的内部,并不会直接刷新到外设

有什么时候会把FILE结构体缓冲区的数据刷新到内核呢?

  • \n
  • 进程退出的时候

从用户级别缓冲区到内核缓冲区的刷新策略种类: (从OS->硬件同样适用)

  • 立即刷新 (不缓冲)
  • 行刷新 (行缓冲\n),比如显示器就是这种刷新策略
  • 全缓冲(缓冲区满了才刷新),比如向磁盘文件写入数据

当发生 重定向的时候 (由刷新到显示器 -> 刷新到文件当中) :隐含着刷新策略由 行缓冲 变为 全缓冲


image-20220702112128312

此时我们再来解释上面的原因: printf/fprintf进行写入,这些写入的消息都被放到用户缓冲区当中,C缓冲区可能并没有被写满,所以这部分内容并没有立即被刷新到内核当中 (全缓冲刷新策略)

  • 最后如果在进程退出之前close, 此时我们的数据还在用户级缓冲区, 因为把文件描述符关闭了,所以没有地方去刷新,因此什么也没有看到

  • 如果最后没有调close, 则在 **进程退出的时候,**把数据刷新到内核缓冲区当中,然后由OS把数据同步到硬件上,所以我们就能看到由东西输出


如果最后close,也想把数据刷新,要怎么办呢?

close之前 fflush(stdout) 强制刷新缓冲区

image-20220702152648643


总结:为什么提前关闭文件描述符发现刚刚写入的数据没了?

因为这批数据写到了用户层缓冲区即stdout所指向的FILE缓冲区当中,所以里面包含的数据并没有被立即刷新到系统层面上,当我们全部写完之后,数据都没有刷新,最后关闭文件描述符它也不可能刷新了,最终文件里面什么都没有了

写完之后,fflush强制刷新,最后关闭文件描述符这个数据就能被我们看到,根本原因就是这个数据被暂时写到了C语言的缓冲区当中

FILE结构里面包含缓冲区,这个缓冲区是用户及缓冲区,所以printf,等C语言接口,先把数据写到C语言的缓冲区,然后定期让C语言刷新到操作系统当中, 刷新的时候,要通过文件描述符,系统调用的接口,来把数据刷新到操作系统当中,如果提前关闭了文件描述符,这个数据也就不会被刷新.所以这个结果看不到


内核缓冲区

当我们刷新用户缓冲区的数据时,并不是直接把用户缓冲区的数据刷新到磁盘或者是显示器当中,而是先将数据刷新到内核缓冲区,然后再由内核缓冲区将数据刷新到磁盘或者显示器上

image-20220703093315500

最后时候没有close(1)的情况我们就不看了, 不难理解 我们来观察最后close(1)的情况:

  • 不管最后有没有close(1), 我们发现重定向之后,标准错误没有重定向,因为我们是重定向1号文件描述符向log.txt文件打印, 文件描述符2对应的-标准错误不受影响,照样向显示器写,并且刷新策略是行刷新

最后close(1)之后, 重定向后只有write写入的内容, 而printf和fprintf的内容经过重定向后都没有被写入到文件当中,这个是什么原因呢?

解析:

1)重定向时,把原本应该显示到显示器的内容显示到文件当中, 潜台词就是刷新策略从 行缓冲 变为 全缓冲, 等进程结束的时候才会把数据刷新到文件当中,而此时我们的数据还在用户级缓冲区, 因为把文件描述符关闭了,所以没有地方去刷新,因此什么也没有看到

2)write是系统调用, 没有通过C语言缓冲区进行暂存,而是直接写到内核缓冲区, 因此关闭文件描述符并不影响重定向


我们再来看下面一段代码: fork创建子进程

image-20220703094745094


当我们往显示器上打印:正常打印 当我们重定向到文件当中: 使用C语言接口的打印重复出现,而系统调用接口并不影响 这是为什么呢?

没有重定向时:

此时每条向显示器写入的信息末尾都有\n ,所以执行可执行程序./myfile向显示器打印的时候, 在fork之前,这批消息就被刷新到显示器上,所以不会打印两份

重定向时:

此时不是向显示器打印,而是写入到文件中**, 潜台词是是刷新策略变了,由行刷新变成了全缓冲** , printf/fprintf/fpus是先写到C语言缓冲区buffer当中,没有写满并不会立即刷新到内核.父进程的缓冲区也是父进程的空间,fork创建子进程,由于父子进程具有独立性,进程退出时要刷新缓冲区,刷新缓冲区的本质就是一种写入,为了维护代码数据独立性,于是就需要对数据进行写时拷贝, 父进程和子进程谁先刷新时就会发生写时拷贝, 因为父子进程都对各自缓冲区的内容刷新, 于是就可以看到文件当中库函数输出的内容有两份

为什么write没有两份呢?

因为它是系统调用接口,直接向内核缓冲区写入,不会暂存在C语言缓冲区, 这也应证了C语言缓冲区不在OS内,而是在用户层 因为如果说这个缓冲区是操作系统自带的,那么printf,fputs,write函数打印的数据重定向到文件都应该打印1次


那么如何修改可以让创建子进程,而输出的消息也只有一份呢?

在fork之前,fflush强制刷新缓冲区

image-20220703100320124

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

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

相关文章

自己制作投票链接网上投票链接制作可以投票的链接制作

近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&#xff0c;因为它有非常大的优势。1.它比起微信公众号自带的投票系统、传统的H5投票系统有可以图…

RK3568平台开发系列讲解(设备驱动篇)Pinctrl子系统详解

🚀返回专栏总目录 文章目录 一、pinctrl子系统结构描述二、重要的概念三、主要的数据结构和接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢我们知道在许多soc内部包含有多个pin控制器,通过pin控制器的寄存器,我们可以配置一个或者一组引脚的功能和特性。Linux…

K8S篇之pod及生命周期

文章目录Pod 概览pod使用方式Pod 中如何管理多个容器Pod 和控制器Pod 模板Pod 更新与替换静态 Pod容器探针pod的生命周期Pod 阶段容器状态容器重启策略Pod 状况pod readinessGates容器探针检查机制execgrpchttpGettcpSocket探测结果探测类型livenessProbe&#xff08;存活探针&…

【JDK8新特性之Lambda表达式-案例实操】

一.JDK8新特性之Lambda表达式-案例实操 之前我们学习了Stream流相关的内容&#xff0c;如果想看的同学可以看一下之前的文章&#xff0c;接下来我们就来学习和Lambda表达式有关的内容。 二.Lambda表达式案例实操 2.1 最原始创建线程案例版本 创建一个新的线程&#xff0c;指定…

[docker]Sealer简介

文章目录安装创建集群清理集群本机免密登录镜像构建与运行KubefileSealer ImageClusterfilesealer是阿里开源的一款分布式应用打包交付运行的解决方案&#xff1b;通过把分布式应用及其所依赖的数据库、中间件等一起打包成一个集群镜像&#xff0c;解决复杂应用的交付问题。安装…

阿里云服务器部署SpringBoot+Vue项目(宝塔面板傻瓜式操作)

准备工作 一台服务器(我用的是阿里云)SpringBoot项目的jar包Vue项目的dist包 一、购买服务器 然后重置实例密码。 远程连接 登陆成功后安装宝塔面板 二、安装宝塔面板(无账号的注册一个账号) 地址&#xff1a;https://www.bt.cn/new/download.html 选择对应的镜像、不知道…

简易项目:servlet实现个人博客(超级详细)

成品展示博客登录页2.博客预览页博客详情页4.博客编写发布页5.可访问网址http://43.143.248.172:8080/blog_system/login.html用户名:zhangsan密码:123确认需求1.1核心功能1.1.1用户登陆和注销这一部分需要满足用户的登入和注销操作&#xff0c;同时需要判断用户名和密码的正确…

【ArcGIS Pro二次开发】(8):图层(Layer)的基本操作

在ArcGIS中&#xff0c;图层(Layer)是地理数据的集合。可以在 ArcGIS Pro中将很多不同类型的数据表示为图层。 图层通常包含矢量&#xff08;要素&#xff09;或栅格数据。 图层的类型取决于您拥有的数据类型、其基础结构以及其他一些变量。 一、图层(Layer)的基本操作示例 以…

华为OD机试题,用 Java 解【矩阵最大值】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

python-在macOS上安装python库 xlwings失败的解决方式

问题&#xff1a;python库 xlwings安装失败 今天&#xff0c;看到网上有wlwings库&#xff0c;可以用来处理excel表格&#xff0c;立刻想试一试。结果&#xff0c;安装这个python库失败了。经过排查&#xff0c;问题解决。 安装过程和错误提示&#xff1a; 我用最简单直接的…

【linux】进程间通信——system V

system V一、system V介绍二 、共享内存2.1 共享内存的原理2.2 共享内存接口2.2.1 创建共享内存shmget2.2.2 查看IPC资源2.2.3 共享内存的控制shmctl2.2.4 共享内存的关联shmat2.2.5 共享内存的去关联shmdt2.3 进程间通信2.4 共享内存的特性2.5 共享内存的大小三、消息队列3.1 …

【Virtualization】Windows11安装VMware Workstation后异常处置

安装环境 Windows 11 专业版 22H2 build 22621.1265 VMware Workstation 17 Pro 17.0.0 build-20800274 存在问题 原因分析 1、BIOS未开启虚拟化。 2、操作系统启用的虚拟化与Workstation冲突。 3、操作系统启用内核隔离-内存完整性保护。 处置思路 1、打开“资源管理器”…

MyBatis学习笔记(六) —— MyBatis的各种查询功能

6、MyBatis的各种查询功能 6.1、查询一个实体类对象 SelectMapper.java接口 /*** 根据用户id查询用户信息* param id* return*/ User getUserById(Param("id") int id);SelectMapper.xml <!--User getUserById(Param("id") int id)--> <selec…

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)

目录1.搬砖1.题目描述2.输入格式3.输出格式4.样例输入5.样例输出6.数据范围7.原题链接2.解题思路3.Ac_code1.搬砖 1.题目描述 这天&#xff0c;小明在搬砖。 他一共有 nnn 块砖, 他发现第 iii 砖的重量为 wiw_{i}wi​, 价值为 viv_{i}vi​ 。他突然想从这些 砖中选一些出来从…

JVM的内存结构

一.引言 1.什么是 JVM &#xff1f; 1&#xff09;定义&#xff1a; Java Virtual Machine - java 程序的运行环境&#xff08;java 二进制字节码的运行环境&#xff09; 2&#xff09;好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收功能…

在服务器上指定GPU跑代码

一、准备工作 查看GPU状态和信息&#xff0c;找到空闲的GPU&#xff1a; nvidia-smi 二、指定单GPU 从图中 Processes 表格我们可以发现0、1、2号GPU均是可以利用的。于是我们可以在python文件中加入以下代码&#xff0c;表示使用0号GPU&#xff1a; import os os.environ…

【数通网络交换基础梳理2】三层设备、网关、ARP表、VLAN、路由表及跨网段路由下一跳转发原理

一、不同网段如何通讯 同网段可以依靠二层交换机通讯&#xff0c;网络中存在多个网段192.168.1.1/24 172.16.1.1/24 173.73.1.1/24情况下如何互相通讯&#xff1f;上节留一下的问题&#xff0c;这节继续讲解。 1、这里以Ping命令讲解&#xff0c;PC1 ping173.73.1.2&#xf…

2023中职组网络安全技能竞赛——代码审计解析(超级详细)

代码审计:需求环境可私信博主 任务环境说明: 服务器场景:PYsystem0035服务器场景操作系统:未知服务器场景用户名:未知 密码:未知在渗透机Kali Linux中访问靶机服务器Web页面,注册账号并登陆,找到存在XSS执行漏洞的页面,将该页面中存在XSS执行漏洞的对象名作为FLAG提…

关于永中Office(永中办公软件)不认Windows系统安装的字体的解决办法

一位网友的电脑最近安装了永中Office软件&#xff0c;在使用过程中发现无法使用方正小标宋简体、仿宋GB2312等字体&#xff0c;这些字体在之前所用的微软Office中可以正常使用。他根据网上查到的一些的资料&#xff0c;将这些字体文件复制到C:\Program Files\Yozosoft\Yozo_Off…

【Java】CAS锁

一、什么是CAS机制&#xff08;compare and swap&#xff09; 1.概述 CAS的全称为Compare-And-Swap&#xff0c;直译就是对比交换。是一条CPU的原子指令&#xff0c;其作用是让CPU先进行比较两个值是否相等&#xff0c;然后原子地更新某个位置的值。经过调查发现&#xff0c;…