Linux学习总结

Linux笔记(一)

inode(信息节点):其存储着文件关联的元数据,如它的修改时间戳、所有者、类型、长度以及文件的数据的地址-唯独没有文件名

目录:将易读的名字和indoe编号进行映射。名字与inode的配对,称为链接(Link). 目录可以嵌套到别的目录
目录不能像普通文件那样打开和操作它们,他们必须通过几个特殊的系统调用来操作他们,且仅允许两个操作:添加链接和删除链接。

硬链接:我们将不同名字映射到同一个indoe信息节点的多个链接称为硬链接。

删除目录结构中的一个文件将会引发一个unlink操作,将文件名和inode的映射信息从目录中移除。
由于linux存在硬链接,所以得等到所有的链接都移除后才能彻底的删除文件,则每个inode中包括着一个链接计数来跟踪文件系统中的指向该文件的硬链接的数目,当链接计数为0时才能真正的从文件系统中删除

符号链接(symlinks):可以跨越文件系统建立链接.每个symlinks都有自己的inode和包含链接文件完整路径名和数据块。

特殊文件:如块设备文件、字符设备文件、命名管道和Unix域套接字。

扇区:块设备最小访问地址单元,通常为512字节

块:文件系统中最小的逻辑地址单元,一般大于扇区的大小,但是小于页(最小可访问的内存管理单元,一个硬件部件)的大小,普通块的大小通常为512B、1KB和4KB。

命名空间:Linux支持进程独立的名字空间,允许每一个进程拥有一个系统文件和目录层次的唯一视图。子进程继承父进程的名字空间,但是一个进程可以通过选择一系列挂载节点和独立的根目录来创建自己的命名空间

进程:程序的执行实例被成为进程

线程:一个进程包含一个或多个执行线程,线程是进程中的活动单位。
进程树:在linux中进程的严格的层次结构。进程树以第一个进程,也就是init进程为根。新进程通过fork()系统调用创建。fork()复制了调用进程,则原进程为父进程,新进程为子进程。除了第一个进程外,每一个进程都有父进程。如果父进程在先于子进程终止,内核将init进程指定为其父进程。如果进程终止,它并不会立即从系统中移除。相反,内核将在内存中保存进程的部分内容,允许父进程查询该进程的终止状态,这被称为终止进程等待。如一个进程已经终止,但父进程尚未获知它的终止状态,则称为僵尸进程。
用户ID:每个用户关联的唯一正整数。uid 0 是超级用户root的id。
权限:
信号:是一种单向异步通知机制。信号可以从内核发送到进程,也可能是从进程到进程,或者进程给自己。信号一般用于通知进程发生某些事件。

进程之间通讯:允许进程交换信息和通知彼此所发生的事件。通讯机制包括管道、命名管道、信号量、消息队列、共享内存和快速用户空间互斥体。

错误处理:通常通过函数的返回值表示,并通过特殊的变量errno来描述。perror()函数打印错误

文件IO

文件描述符(filedescriptors):每打开一个文件都会返回一个文件描述符。文件描述符由C语言的int类型表示。从0开始,默认上限为1024,则最大默认值为1023,但是最多可以将该值设定为1048576.负数不是合法的文件描述符,所以-1表示常常表示用来一个函数不能返回合法文件描述符的错误。
每个进程按照惯例至少有三个打开的文件描述符:0、1和2,除非进程显式的关闭它们。0为标准输入(stdin),1为标准输出(stdout),2为标准错误(stderr).文件描述符总是取最小的值,若关闭了0,则打开下一个文件时,文件描述符为0,就将0的输出修改了。

打开文件:最基本的访问文件的方法是使用read()和write()系统调用。在一个文件能被访问之前,必须通过open()和creat()系统调用打开它。一旦使用完毕,就应该用close()系统调用关闭文件。

open()

打开一个文件并获得一个文件描述符
头文件为

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open (const char *name, int flags);
int open (const char *name, int flags, mode_t mode);

flags参数:    O_RDONLY 只读
O_WRONLY 只写
O_RDWR   可读可写

flags参数可以和以下多个值进行按位或运算,用于修改打开文件请求的行为。
O_APPEND 文件将以追加模式下打开。就是总是将文件位置指针将被置于文件末尾。
O_ASYNC 当指定文件可写或可读时产生一个信号(默认为SIGIO)
O_CREAT 当name指定的文件不存在时,将由内核来创建。
O_DIRECT 打开文件用于直接I/O
O_DIRECTORY 如果name不是一个目录,open()会调用失败。
O_EXCL 和O_CREAT一起给出的时候,如果由name给定的文件已经存在,则open()调用失败。防止文件创建时出现竞争。
O_LARGEFILE 给定文件打开时将使用64位偏移量,这样可以使得大于2G的文件能够被打开
O_NOCTTY 如果给出的name指向一个终端设备,它将不会成为这个进程的控制终端
O_NOFOLLOW 如果name是一个符号链接,open()调用会失败
O_NONBLOCK 如果可以,文件将在非阻塞模式下打开。
O_SYNC 打开文件用于同步I/O.
O_TRUNC 如果文件存在,且为普通文件,并允许写,将文件的长度截断为0.

open()中的mode参数为设置新文件的权限,当创建新文件时,需要给出mode参数
mode可以直接使用三位8进制来设置新文件的权限,或者使用库设定一组可以进行按位或操作的常数。

creat()函数:创建新文件

    头文件为

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat (const char *name, mode_t mode);

read()读取文件

使用打开文件时返回的文件描述符读取文件

            #include <unistd.h>
            ssize_t read (int fd, void *buf, size_t len);

read()大小限制:size_t和ssize_t类型由POSIX确定。size_t类型用来存储用字节衡量大小的值。ssize_t类型是有符号的size_t类型
size_t的最大值为SIZE_MAX;ssize_t的最大值为SSIZE_MAX.如果len大于SSIZE_T,则read()调用结果是未定义的。

write():写文件

#include <unistd.h>
ssize_t write (int fd, const void *buf, size_t count);

阻塞:当进程调用一个阻塞的系统函数时,该进程被置于睡眠的状态,这时内核调度其他进程运行,直到该进程等待的事件发生了它才有可能继续运行。
非阻塞写:直接返回,不会阻塞,调用者需要试着再读一次
write()大小限制:如果count比SSIZE_MAX还大,write()调用结果是未定义的。count值为零的write()调用将立即返回返回值为0.
当一个write()调用返回时,内核已将所提供的缓冲区数据复制到了内核缓冲区中,但却没有保证数据写到目的文件中。

同步I/O:

#include <unistd.h>
int fsync (int fd);

调用fsync()可以保证fd对应文件的脏数据回写到磁盘上,文件描述符fd必须是以写方式打开的。且在驱动器确认数据已经全部写入之前不会返回。

int fdatasync (int fd);

fdatasync()和fsync()一样,区别它仅写入数据。
两个成功都返回0,失败返回-1.

#include <unistd.h>
void sync (void);
sync()

系统调用可以用来对磁盘上的的所有缓冲区进行同步。调用时会启动将整个缓冲区写入磁盘的过程。

int fd;
fd = open (file, O_WRONLY | O_SYNC);
if (fd == -1) {
    perror (”open”);
    return -1;
}

O_SYNC标志使得读请求总是同步的。

映射文件到内存

函数mmap()将某个文件的指定内容映射到内存空间中,普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read()和write()等操作。函数声明如下

#include<sys/mman.h>
void *mmap(void *start, size_t length, int port, int flags, int fd, off_t offset);

start:映射的特定地址,一般设置为NULL,由系统分配。如果自己设置,必须为内存页的大小
length:映射的文件的长度
fd:为映射文件的描述符。
offset:为偏移量,即映射内容在该文件中的起始位置。
prot:描述映射内存权限,有下列选项
PORT_READ:允许读该内存段
PORT_WRITE:允许写改内存段
PORT_EXEC:允许执行该内存段
PORT_NONE:该内存段部能被访问。
flags:控制程序对该内存段改变所造成的影响
MAP_PRIVATE:内存段是私有的,对它的修改只在此局部范围内有效,其他进程不可见。
MAP_SHARED:共享映射,某进程对该段内存空间的更新对其他进程来说是可见的,但是该文件的更新的内容并不会立即更新,若需要更新文件内容,需要调用msync()和munmap()函数
如果需要解除映射,则可以调用munmap()函数,相应的内容修改将会写到磁盘文件中,

int munmap(void *start, size_t length);

如果希望立即将资料写入文件中,可以调用msync()函数

int msync(const void *start, size_t length, int flags);

start为内存开始位置,length为长度。flags的选项如下:
MS_ASYNC:请内核尽快将资料写入到文件
MS_SYNC:在此函数结束返回前将资料写入文件
MS_INVALIDATE:让内核自行决定是否写入,仅在特殊状况下使用。
当多任务操作系统环境中,如果两个进程并发对同一个文件进行写操作,可能会导致该文件遭到破坏。可以通过对文件的锁操作来解决这个问题。
函数flock()和fcntl()都可以对文件的锁操作,但flock()函数flock只能锁定整个文件,flcntl()可以提供任意文件位置的锁定。

打开/关闭目录文件

函数opendir()和closedir()用于打开和关闭文件,返回一个目录流指针。

#include<direnth>
DIR *opendir(const char *dirname);
int closedir(DIR *dirp);

opendir()打开路径为dirname的目录,并使用一个目录流指针。如果执行失败,将返回NULL,并设置全局变量errno, 以指示错误
closedir()用于关闭指定的目录流,然后释放与DIR指针关联的结构。如果成功执行,则返回值-1,并设置errno指示错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值