文件指针

Linux操作系统 内存管理、用户操作和文件操作

﹥>﹥吖頭↗ 提交于 2019-12-08 05:16:21
内存管理、用户操作和文件操作 预备知识: 1、Linux系统的内存分为物理内存和虚拟内存。 物理内存 是指安装在计算机当中的主存储器; 虚拟内存 是 一段 虚拟的逻辑上连续的储存空间, 虚拟内存是由多个内存碎片组成,只有 正在使用的 虚拟内存被存放在 内存 上,对于暂时不使用的虚拟内存空间其实是储存在 外存 中。虚拟内存空间地址和实际的物理内存空间地址存在某种逻辑上的关系,如果虚拟内存空间地址的内容将被使用,通过逻辑关系可以计算出此部分内容对应的实际物理内存空间,然后将内容加载到内存中。虚拟内存在 一定程度上 独立于物理内存。 2、计算机的物理 内存空间有限(虚拟内存只要运行部分占用物理内存空间) 而且不同PC的 物理内存是不一样(通过虚拟内存空间,进程中代码的访存操作的地址全部是这个内存空间的地址) ,所以进程使用的是 虚拟内存空间 。 3、内存的最小粒度是页,进程虚拟地址空间和内存的映射也是以页为单位。页(面)的大小称为页面的大小,大小应该为2的幂。页号P=A/L;A表示逻辑地址空间中的地址(虚拟内存空间地址),L表示页面大小。 4、物理块:将内存的物理地址空间划分为若干块,称为物理块,物理块与页(面)一一对应。 5、页表储存在物理内存中,由操作系统维护。CPU中有一个 页表寄存器 ,里面存放着当前进程页表的 起始地址和页表长度

文件描述符fd,struct files_struct

安稳与你 提交于 2019-12-06 04:16:37
程序可以理解为硬盘上的普通二进制文件;进程是加载到内存中的二进制文件,除了加载到内存中的二进制文件外,还附有所有对于该二进制文件 描述信息的结构体 ,描述该进程的结构体叫 PCB(进程控制块) ,在这就不在讨论。对于程序与进程,也就可以简单地理解为是否有PCB(进程控制块)。下面我们再来讨论PCB与file_struct的关系。 在每一个PCB中,都有一个文件描述符表,通过文件描述符索引指向file_struct(系统打开文件表) 。 文件描述符在形式上是一个非负整数,实际上, 它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表 ,当程序打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。也就是说,一个程序能够访问文件是因为给这个程序分配了文件描述符。 下面我们来讨论file_struct里面具体有哪些内容, file结构体定义在linux系统中的(/kernels/include/linus/fs.h)文件中。 file_struct结构如下 struct file {   union {   struct list_head fu_list; //文件对象链表指针linux/include/linux/list.h   struct rcu_head fu_rcuhead; //RCU(Read-Copy Update)是Linux 2

文件指针与文件描述符

本小妞迷上赌 提交于 2019-12-06 03:18:39
目录 文件指针与文件描述符 概念 缓冲 title: 文件指针与文件描述符 date: 2019/11/28 20:01:12 toc: true --- 文件指针与文件描述符 概念 文件描述符是针对内核的,是一个非负的整数,每个进程的描述符是独立的,标准输入输出和错误是 STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO ,定义在 unistd.h ,对应的是 open 系列的函数 文件指针是 FILE * 结构指针,标准输入输出和错误对应的文件指针是 stdin,stdout,stderr ,定义在 stdio.h ,对应的是 fopen 系列的函数 缓冲 文件指针是标准IO库的具体实现,标准IO的一个最大的特色就是提供缓冲,加快速度. 全缓冲 行缓冲,默认值在 stdio.h , #define BUFSIZ 8192 无缓冲 #include <stdio.h> // 注意 如果参数没有size的,要确保缓冲长度大于 BUFSIZ 这个值定义在 stdio.h /* Default buffer size. */ #define BUFSIZ 8192 void setbuf(FILE *stream, char *buf); void setbuffer(FILE *stream, char *buf, size_t size); void

Delphi(ObjectPascal)基础语法

a 夏天 提交于 2019-12-05 22:18:08
一个程序分为两个部分: 1、程序首部: program 来标识这是一个pascal程序 后面的是可执行文件的名称 程序名称 2、程序体: 说明部分:数据先定义后使用 执行部分:以begin开始,以end结束 之后一个.表示整个程序的结束 uses 项目引用的其他文件,系统创建的单元文件或是用户创建的的单元文件 接口部分不能相互引用,实现部分可以 所有单元隐式引用system.pas {$R *.res}是编译器指令,告诉编译器去链接一个资源文件,在项目同名、后缀为 .res的文件查找windows资源信息 单元文件.pas: 应用程序的源代码 自定义单元: unit 单元名;一定要与pas文件一致 interface <公共说明部分> 用于声明对其他单元该部分是可以访问的—即可以从该单元中访问哪些东西,没有运行代码 uses引用了系统预先定义的单元文件 接口部分包括了类型声明、变量声明、常数 implementation <私有说明部分> 包括了代码实现部分和隐含部分 uses引用了程序实现部分引用的单元文件,在用户当前项目中创建的 实现部分包括了类型声明、变量声明、常数和过程—只能在单元内使用 定义在实现部分的过程和函数如果接口部分没有相应的声明,则只能在单元内部使用 {$R *.dfm} 范围检查打开 定义资源文件 begin/initialization <初始化部分>

从内核文件系统看文件读写过程(转)

荒凉一梦 提交于 2019-12-05 15:31:33
系统调用 操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境,但是计算机系统的各种硬件资源是有限的,因此为了保证每一个进程都能安全的执行,处理器设有两种模式:“用户模式”与“内核模式”。一些 容易发生安全问题的操作都被限制在只有内核模式 下才可以执行,例如I/O操作,修改基址寄存器内容等。而 连接用户模式和内核模式的接口称之为系统调用 。 应用程序代码运行在用户模式下,当应用程序需要实现内核模式下的指令时,先向操作系统发送调用请求。 操作系统收到请求后,执行系统调用接口,使处理器进入内核模式 。当处理器 处理完系统调用操作后,操作系统会让处理器返回用户模式,继续执行用户代码 。 进程的虚拟地址空间可分为两部分, 内核空间和用户空间 。内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们 都处于虚拟空间中,都是对物理地址的映射 。 应用程序中 实现对文件的操作过程就是典型的系统调用过程 。 回到顶部 虚拟文件系统 一个操作系统可以支持多种底层不同的文件系统(比如NTFS, FAT, ext3, ext4),为了给内核和用户进程提供统一的文件系统视图,Linux在用户进程和底层文件系统之间加入了一个抽象层,即虚拟文件系统(Virtual File System, VFS),进程所有的文件操作都通过VFS

MySQL索引底层实现

被刻印的时光 ゝ 提交于 2019-12-04 07:10:44
  索引是数据结构   每种查找算法都只能应用于特定的数据结构之上,例如二分查找要求被检索数据有序,而二叉树查找只能应用于二叉查找树上,但是数据本身的组织结构不可能完全满足各种数据结构(例如,理论上不可能同时将两列都按顺序进行组织),所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。   上图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在 O ( l o g n 2 ) O(log2n)的复杂度内获取到相应数据。   虽然这是一个货真价实的索引,但是实际的数据库系统几乎没有使用二叉查找树或其进化品种红黑树(red-black tree)实现的,原因会在下文介绍。 B树   B树事实上是一种平衡的多叉查找树,也就是说最多可以开m个叉(m>=2),我们称之为m阶b树 总的来说,m阶B树满足以下条件: 每个节点至多可以拥有m棵子树。 根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶

php常用函数

守給你的承諾、 提交于 2019-12-04 05:56:24
字符串函数 strlen:获取字符串长度,字节长度 substr_count 某字符串出现的次数 substr:字符串截取,获取字符串(按照字节进行截取) mb_strlenmb_substr strchr:与substr相似,从指定位置截取一直到最后 strrchr(获取文件后缀名):与strchr一样,只是从右边开始查找字符 strtolower:所有的字符都小写(针对英文字母) strtoupper:所有的字符都大写 strrev:字符串反转(只能反转英文:英文存储只有一个字节),按照字节进行反转 strpos:从字符串中找对应字符出现的位置(数字下标),从最左边开始找 strrpos:与strpos一样,只是从字符串的右边开始找 trim:去掉函数两边的字符,默认是空格 str_split 函数把字符串分割到数组中。 chunk_split() 函数把字符串分割为一连串更小的部分 str_repeat("Shanghai",5);把字符串 "Shanghai " 重复 5 次 str_replace('\\', '/', dirname(__DIR__))); 替换 ucfirst 首字母大写 2时间日期函数 time:得到当前时间的时间戳(整型:从格林威治时间1970年1月1日0时0分0秒开始)秒数 date:时间序列化函数,将指定的时间戳转换成规定时间日期的显示格式

C++->文件流的输入输出

自闭症网瘾萝莉.ら 提交于 2019-12-03 23:17:00
C++->文件流的输入输出 1.书本里以“简单事务处理”为例子,解析二进制输入输出文件流的read和write函数的使用,以及输入输出文件流 过程中指针的捕获、定位,文件流位置的判断,二进制文件转换为文本文件。 1.1.二进制文件流的read函数的原型:read(char *buffer,streamsize size); 1.2.二进制文件流的write函数的原型:write(char *buffer,streamsize size); 注释:这里buffer是一块内存的地址,用来存储或读出数据。参数size是一个整数值,表示用从缓存(buffer)中读出或写入的字 符数。 1.3.移动,获取指针位置函数 1.3.1.移动读、写指针位置 istream&/input.seekg(20,ios::beg); //以流开始位置为基准,后移20个字 istream&/input.seekg(-10,ios::cur); //以指针当前位置为基准,前移10个字 istream&/input.seekg(-10,ios::end); //以指针结尾位置为基准,前移10个字 ostream&/output.seekp()移动(写读)指针位置与seekg类似, ostream&/output.seekp(120); //output流的写指针移到第120个(字节)处 input.tellg(

Git 核心概念

女生的网名这么多〃 提交于 2019-12-03 20:21:27
原文链接 Git的核心概念 聪聪的个人网站 本文不是Git使用教学篇,而是偏向理论方面,旨在更加深刻的理解Git,这样才能更好的使用它,让工具成为我们得力的助手。 版本控制系统 Git 是目前世界上最优秀的分布式版本控制系统。版本控制系统是能够随着时间的推进记录一系列文件的变化以便于你以后想要的退回到某个版本的系统。版本控制系统分为三大类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统 本地版本控制(Local Version Control Systems)是将文件的各个版本以一定的数据格式存储在本地的磁盘(有的VCS 是保存文件的变化补丁,即在文件内容变化时计算出差量保存起来),这种方式在一定程度上解决了手动复制粘贴的问题,但无法解决多人协作的问题。 本地版本控制 集中式版本控制(Centralized Version Control Systems)相比本地版本控制没有什么本质的变化,只是多了个一个中央服务器,各个版本的数据库存储在中央服务器,管理员可以控制开发人员的权限,而 开发人员也可以从中央服务器拉取数据。集中式版本控制虽然解决了团队协作问题,但缺点也很明显:所有数据存储在中央服务器,服务器一旦宕机或者磁盘损坏, 会造成不可估量的损失。 集中式版本控制 分布式版本控制( Distributed Version Control System)与前两者均不同。首先

整理

梦想与她 提交于 2019-12-03 08:07:24
操作系统 1. 进程与线程的本质区别、以及各自的使用场景 答:进程是操作系统分配资源的基本单位,线程是cpu调度的基本单位。 线程非共享的,errno变量,独立的栈空间,未决信号集,寄存器和栈指针(指向内核栈) 线程的优点: 通信方便(socket,fifo,pipe,mmap,消息队列),共享数据方便 开销小,提高了程序的并发性 线程的缺点: 库函数调用,并不稳定,对信号不友好(信号的处理方式是共享的),调试困难,不支持gdb 各自的使用场景: 线程:在等待I/O的时候,可以交给一个线程去做,继续去做别的事情 进程:需要安全稳定的时候使用线程,虽然创建一个进程的花费比线程一个大 2. 线程可以看做寄存器和栈的集合,这句话怎么理解? 答: 首先,从内核的角度来看,线程和进程是类似的,都拥有独立的pcb。但是每个线程都有各自的任务需要去执行,这些都保存在各自的寄存器和栈中。在线程中调用函数的时候,是通过栈帧结构实现的。调用函数的时候,将 函数参数,返回地址,ebp指针,esp指针压入栈中进行保存。然后移动ebp指针和esp指针重新为函数创建一个栈帧结构。 因为ebp指针和sep指针的值是储存在寄存器中,并且函数运行空间的申请,参数,函数地址的保存等需要通过栈来实现,所以,线程可以看做寄存器和栈的集合 3. 线程号和线程ID的区别? 线程号是cpu分配时间轮片的依据