操作系统基础

一、进程与线程

1.进程:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

线程:线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

二者关系:一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

2.进程状态:
就绪态:进程已经具备运行条件,但是CPU还没有分配过来;
运行态:进程占用CPU,并在CPU上运行;
阻塞态:进程因等待某件事发生而暂时不能运行;

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。孤儿进程没有父进程来回收,重任就交给了init进程上,在孤儿进程结束后init会作为父进程进行回收,所以孤儿进程一般没有什么危害。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。若一个进程产生子进程后不调用wait()或waitpid()的话,那么子进程退出后的进程描述符不会释放,进程号也就一直被占用,但是系统使用的进程号是有限的,如果大量产生僵尸进程,就有可能导致系统没有可用的进程号了而不能产生新进程,这就是僵尸进程的危害。
僵尸进程解决办法:子进程在exit()退出之后,内核会释放掉进程的相关资源,留下进程描述符等一些信息等待父进程回收,这个状态称为僵尸进程,这时用ps命令就能看到子进程的转态是“Z”。退出的同时也会给父进程发送一个SIGCHILD信号。
办法一:父进程主动接收并处理SIGCHILD信号,在信号处理函数中调用wait()函数进程处理。
方法二:当父进程陷入死循环等无法处理僵尸进程时,强制杀死父进程,那么它的子进程,即僵尸进程会变成孤儿进程,由系统来回收。
方法三:当系统重启时,所有进程在系统关闭时被停止,包括僵尸进程,开启时init进程会重新加载其他进程。

3.进程间通信
无名管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。
有名管道 (named pipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
套接字( socket ) : 套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

4.CPU调度算法(考虑因素:1.吞吐量2.CPU利用率3.周转时间4.公平性)
先来先服务(FCFS):作业调度中,算法每次从后备作业队列中选择最先进入该队列的一个或几个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列。在进程调度中,FCFS调度算法每次从就绪队列中选择最先进入该队列的进程,将处理机分配给它,使之投入运行,直到完成或因某种原因而阻塞时才释放处理机。
特点:算法简单,效率低;有利于长作业;有利于CPU繁忙型作业,不利于I/O繁忙型作业。

短作业优先(SJF):短作业优先(SJF)调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法,则是从就绪队列中选择一个估计运行时间最短的进程,将处理机分配给它,使之立即执行,直到完成或发生某事件而阻塞时,才释放处理机。
特点:对长作业不利,周转时间增加,“饥饿”现象,未考虑作业紧迫程度,该算法平均等待时间和平均周转时间最少。

优先级调度:该算法中的优先级用于描述作业运行的紧迫程度。在作业调度中,优先级调度算法每次从后备作业队列中选择优先级最髙的一个或几个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列。在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。

根据新的更高优先级进程能否抢占正在执行的进程,可将该调度算法分为:
非剥夺式优先级调度算法:当某一个进程正在处理机上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在运行的进程继续运行,直到由于其自身的原因而主动让出处理机时(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。
剥夺式优先级调度算法:当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。

而根据进程创建后其优先级是否可以改变,可以将进程优先级分为以下两种:
静态优先级:优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。
动态优先级:在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据为进程占有CPU时间的长短、就绪进程等待CPU时间的长短。

高响应比优先调度算法:高响应比优先调度算法主要用于作业调度,该算法是对FCFS调度算法和SJF调度算法的一种综合平衡,同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。

时间片轮转调度:主要适用于分时系统。在这种算法中,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程序总是选择就绪队列中第一个进程执行,即先来先服务的原则,但仅能运行一个时间片,如100ms。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。

多级反馈队列调度:是时间片轮转调度算法和优先级调度算法的综合和发展。通过动态调整进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。例如,为提高系统吞吐量和缩短平均周转时间而照顾短进程;为获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程;同时,也不必事先估计进程的执行时间。

5.进程同步:
信号量:用于进程间传递信号的一个整数值。在信号量上只有三种操作可以进行:初始化,P操作和V操作,这三种操作都是原子操作。
P操作(递减操作)可以用于阻塞一个进程,V操作(增加操作)可以用于解除阻塞一个进程。
基本原理是两个或多个进程可以通过简单的信号进行合作,一个进程可以被迫在某一位置停止,直到它接收到一个特定的信号。该信号即为信号量s。
为通过信号量s传送信号,进程可执行原语semSignal(s);
为通过信号量s接收信号,进程可执行原语semWait(s);
如果相应的信号仍然没有发送,则进程被阻塞,直到发送完为止。
可把信号量视为一个具有整数值的变量,在它之上定义三个操作:
一个信号量可以初始化为非负数
semWait操作使信号量s减1.若值为负数,则执行semWait的进程被阻塞。否则进程继续执行。
semSignal操作使信号量加1,若值大于或等于零,则被semWait操作阻塞的进程被解除阻塞。

管程:管程是由一个或多个过程、一个初始化序列和局部数据组成的软件模块,其主要特点如下:
局部数据变量只能被管程的过程访问,任何外部过程都不能访问。
一个进程通过调用管程的一个过程进入管程。
在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用。
管程通过使用条件变量提供对同步的支持,这些条件变量包含在管程中,并且只有在管程中才能被访问。有两个函数可以操作条件变量:
cwait(c):调用进程的执行在条件c上阻塞,管程现在可被另一个进程使用。
csignal(c):恢复执行在cwait之后因为某些条件而阻塞的进程。如果有多个这样的进程,选择其中一个;如果没有这样的进程,什么也不做。

消息传递:消息传递的实际功能以一对原语的形式提供:
send(destination,message)
receive(source,message)
这是进程间进程消息传递所需要的最小操作集。
一个进程以消息的形式给另一个指定的目标进程发送消息;
进程通过执行receive原语接收消息,receive原语中指明发送消息的源进程和消息。

6.临界区是指必须以互斥的方式执行的代码段,也就是说临界区范围内只能由一个活动的线程。例如:修改共享变量的过程中其他的执行线程可能会访问共享变量,那么修改共享变量的代码就被看成是临界区的一部分。
信号量:信号量是(S)一个整型变量,它带有两个原子操作信号量锁定wait和信号量解锁signal。
可以将其看成一个整数值和一个等待signal操作的进程列表。
wait操作:
如果S大于零,wait就在一个原子操作中测试S,并对其进行减量运算;
如果S等于零,wait就在一个原子操作中测试S,并阻塞调用程序。
signal操作:
如果有线程在信号量上阻塞,S就等于零,signal就会解除对某个等待线程的阻塞;
如果没有线程在信号量上阻塞,signal就对S进行增量运算。

7.同步模型
生产者消费者:也叫缓存绑定问题(bounded- buffer),是一个经典的、多进程同步问题。即有两个进程:制造商和消费者,共享一个固定大小的缓存。制造商的工作是制造一段数据,放进缓存,如此反复。同时,消费者则一次消费一段数据(即将其从缓存中移出)。问题的核心就是要保证不让制造商在缓存还是满的时候仍然要向内写数据,不让消费者试图从空的缓存中取出数据。
信号标
单消费者单制造商
多消费者多制造商

哲学家就餐:设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿时才试图分两次从两边拿起筷子就餐。
条件:
1)拿到两只筷子时哲学家才开始吃饭。
2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子。
3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子。
解释死锁和资源耗尽
服务生解法
资源分级解法
Chandy/Misra解法

读者-写者:第一和第二读者-作者问题是并行计算的模拟。这两个问题描述的是有许多线程必须同时访问共享的内存地址,有的要读,有的要写。在通常的限制条件下,在一个进程正在写入的时候,其它的进程不能读,也不能写那个共享的内存块。特别要说的是,两个或多个读者可以同时访问同一内存地址。一般来说,会使用一种叫“读-写锁”(readers-writer lock)的数据结构来解决这类问题。
第一读者-作者问题
第二读者-作者问题
第三读者-作者问题

理发师问题:假设有一个理发店只有一个理发师,一张理发时坐的椅子,若干张普通椅子顾客供等候时坐。没有顾客时,理发师就坐在理发的椅子上睡觉。顾客一到,他不是叫醒理发师,就是离开。如果理发师没有睡觉,而在为别人理发,他就会坐下来等候。如果所有的枯木都坐满了人,最后来的顾客就会离开。
三个信号标,顾客信号标,理发师信号标,互斥信号标

三个烟鬼问题:假设一支香烟需要:1、烟草;2、卷烟纸;3、一根火柴。
假设一张圆桌上围座着三烟鬼。他们每个人都能提供无穷多的材料:一个有无穷多的烟草;一个有无穷多的卷烟纸;一个有无穷多的火柴。
假设还有一个不吸烟的协调人。他每次都会公正地要求两个人取出一份材料放到桌,然后通知第三个人。第三个人从桌上拿走另外两个人的材料,再加上自己的一份,卷一枝烟就会抽起来。这时,协调人看到桌上空了,就会再次随机叫两人向桌上贡献自己的材料。这个过程会无限地进行下去。
不会有人把桌上的东西藏起来。只有当他抽完一枝烟后,才会再卷另一枝。如果协调人将烟草和卷烟纸放到桌上,而那个有火柴的人仍在吸烟,那么烟草、卷烟纸就会原封不动地放在桌上,走到有火柴的人抽完烟取走桌上的材料。
使用二位信号标就可以解决“三个烟鬼的问题”。我们可以定义一个二位信号标数组A,每个烟鬼一个,桌子也有一个对应的二进制信号标T。将烟鬼的信号标初始化为0,桌子的初始化为1。

8.死锁问题
所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。

死锁发生的条件
互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

死锁的解决办法
预防死锁:这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。
避免死锁:该方法同样是属于事先预防的策略,但它并不须事先采取各种限制措施去破坏产生死锁的的四个必要条件,而是在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。
检测死锁:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源,然后采取适当措施,从系统中将已发生的死锁清除掉。
解除死锁:这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

9.线程池原理及作用
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

Java类库提供的线程池java.util.concurrent包

线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。

多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。

线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。

二、内存管理与文件系统 IO

1.物理内存和虚拟内存
用户编制程序时使用的地址称为虚地址或逻辑地址,其对应的存储空间称为虚存空间或逻辑地址空间;而计算机物理内存的访问地址则称为实地址或物理地址,其对应的存储空间称为物理存储空间或主存空间。

2.分页与分段
分页存储管理:用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。
分段存储管理:将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。
分页与分段的主要区别
分页和分段有许多相似之处,比如两者都不要求作业连续存放.但在概念上两者完全不同,主要表现在以下几个方面:
(1)页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要.段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要.
(2)页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的.而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分.
(3)分页的作业地址空间是一维的.分段的地址空间是二维的.

3.页面置换算法
最佳置换算法(OPT)
最佳(Optimal, OPT)置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若千页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。

先进先出页面置换(FIFO)
优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。该算法实现简单,只需把调入内存的页面根据先后次序链接成队列,设置一个指针总指向最早的页面。但该算法与进程实际运行时的规律不适应,因为在进程中,有的页面经常被访问。

最近最久未使用置换(LRU)
选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。

时钟置换(CLOCK)
简单的CLOCK算法是给每一帧关联一个附加位,称为使用位。当某一页首次装入主存时,该帧的使用位设置为1;当该页随后再被访问到时,它的使用位也被置为1。对于页替换算法,用于替换的候选帧集合看做一个循环缓冲区,并且有一个指针与之相关联。当某一页被替换时,该指针被设置成指向缓冲区中的下一帧。当需要替换一页时,操作系统扫描缓冲区,以查找使用位被置为0的一帧。每当遇到一个使用位为1的帧时,操作系统就将该位重新置为0;如果在这个过程开始时,缓冲区中所有帧的使用位均为0,则选择遇到的第一个帧替换;如果所有帧的使用位均为1,则指针在缓冲区中完整地循环一周,把所有使用位都置为0,并且停留在最初的位置上,替换该帧中的页。由于该算法循环地检查各页面的情况,故称为CLOCK算法,又称为最近未用(Not Recently Used, NRU)算法。

4.常见LINUX文件系统
ext2
点是比较简单,文件比较少时性能较好,比较适合文件少的场景,主要缺点如下:
——inode的数量是固定不变的,在格式化分区的时候可以指定inode和数据块所占空间的比例,但一旦格式化好,后续就没法再改变了
——当块大小为4K时,单个文件大小不能超过2TB,分区大小不能超过16TB(目前硬盘大小一般都只有几TB,所以也不是什么大问题,)
——一个目录下最多只能有32000个子目录
——由于目录里面存储的文件和子目录都是以线性方式来组织的,所以遍历目录效率不高,尤其当目录下文件个数达到10K以上规模的时候,速度会明显的变慢
——当底层的磁盘分区空间变大时(使用LVM时很常见),ext2没法动态的扩展来使用增加的空间

ext3
ext3在ext2的基础上实现了下面几个功能,其它的都保持不变,即ext2的缺点ext3也有
——支持日志(Journal)功能,数据的安全性较ext2有很大的提高
——当底层的分区空间变大时,ext3可以自动扩展来使用增加的空间
——使用HTree来组织目录里面的文件和子目录,使目录下的文件和子目录数不再受性能限制(数量超过10K也不会有性能问题)
没有日志(Journal)功能,所以数据的安全性不高

ext4
ext4借鉴了当前成熟的一些文件系统技术,在ext3上增加了一些功能,并且对性能做了一些改进,主要变化如下
——当块大小为4K时,支持的最大文件和最大分区大小分别达到了16TB和1EB
——不再受32000个子目录数的限制,支持不限数量的子目录个数
——支持Extents,提高了大文件的操作性能
——内部实现上支持一次分配多个数据块,较ext3的性能有所提高
——支持延时分配(即支持fallocate函数)(fallocate是libc的函数,在不支持该功能的文件系统上,libc会创建一个占用磁盘空间文件)
——支持在线快速扫描
——支持在线碎片整理(单个文件或者整个分区)
——日志(Journal)支持校验码(checksum),数据的安全性进一步提高
——支持无日志(No Journaling)模式(ext3不支持该功能),这样就和ext2一样,消除了写日志对性能的影响
——支持纳秒级的时间戳
——记录了文件的创建时间,由于相关的应用层工具还不支持,所以只能通过debug的方式看到文件的创建时间

xfs
和ext4相比,xfs不支持下面这些功能:
不支持日志(Journal)校验码
不支持无日志(No Journaling)模式
不支持文件创建时间
不支持数据日志(data journal),只有元数据日志(metadata journal)
但xfs有下面这些特性:
支持的最大文件和分区都达到了8EB
inode动态分配,从而不受inode数量的限制,再也不用担心存储大量小文件导致inode不够用的问题了。
更大的xattr(extended attributes)空间,ext2/3/4及btrfs都限制xattr的长度不能超过一个块(一般是4K),而xfs可以达到64K
内部采用Allocation groups机制,各个group之间没有依赖,支持并发操作,在多核环境的某些场景下性能表现不错
提供了原生的dump和restore工具,并且支持在线dump

brtfs
btrfs是一个和ZFS类似的文件系统,支持的功能非常多,据说将来会替换ext4成为Linux下的默认文件系统。这里列举一些重要的功能
支持的最大文件和分区达到了16EB
支持COW(copy on write)
针对小文件和SSD做了优化
inode动态分配
支持子分区(Subvolumes),子分区可以单独挂载
支持元数据和数据的校验(crc32)
支持压缩,去重
支持多个磁盘和分区,可动态扩展
支持LVM,RAID的功能(有了btrfs,就不再需要lvm和软raid了)
增量备份和恢复
支持快照
将ext2/3/4转换成btrfs(反过来不行)
btrfs最大的缺点就是由于其COW的实现方式,导致碎片化问题比较严重,不太适合频繁写的场景,比如数据库、虚拟机的磁盘文件等。不过大部分场合不需要担心,btrfs有在线的碎片整理工具。

三、Linux基本操作

绝对路径:如/etc/init.d
当前目录和上层目录: ./ ../
主目录: ~/
切换目录: cd
查看当前进程: ps
执行退出: exit
查看当前路径: pwd
清屏: clear
退出当前命令: ctrl+c 彻底退出
执行睡眠 : ctrl+z 挂起当前进程
fg 恢复后台
查看当前用户id: ”id“:查看显示目前登陆账户的 uid 和 gid 及所属分组及用户名
查看指定帮助: 如 man adduser 这个很全 而且有例子; adduser –help 这个告诉你一些常用参数;
info adduesr;

ls执行的功能:列出指定目录中的目录,以及文件
-a 所有文件
-l 详细信息,包括大小字节数,权限

建立软链接:ln -s slink source
建立硬链接:ln link source

创建目录:mkdir
创建文件:如touch、vi等
复制文件:cp
文件权限修改:chmod
格式如下:
chmodu+xfilefile c h m o d u + x f i l e 给 f i l e 的 属 主 增 加 执 行 权 限 chmod 751 file 给 file 的属主分配读、写、执行(7)的权限,给 file 的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限

vi 文件名 #编辑方式查看,可修改
cat 文件名 #显示全部文件内容
more 文件名 #分页显示文件内容
less 文件名 #与 more 相似,更好的是可以往前翻页
tail 文件名 #仅查看尾部,还可以指定行数
head 文件名 #仅查看头部,还可以指定行数

终端路径:/dev/tty
黑洞文件:/dev/null

移动文件:mv

删除文件:rm

命令通配符
“?”可替代单个字符。 ·“*”可替代任意多个字符。 ·方括号“[charset]”可替代 charset 集中的任何单个字符,如[a-z],[abABC]
用什么命令对一个文件的内容进行统计?(行号、单词数、字节数)
wc 命令 - c 统计字节数 - l 统计行数 - w 统计字数。

Grep 命令有什么用?如何忽略大小写?如何查找不含该串的行?
是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。
grep [stringSTRING] filename grep [^string] filename

Linux进程状态
D——不可中断状态:进程处于睡眠状态,但是此刻进程是不可中断的。不可中断, 指进程不响应异步信号。

T——暂停状态/跟踪状态:向进程发送一个 SIGSTOP 信号,它就会因响应该信号 而进入 TASK_STOPPED 状态;当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。

R——就绪状态:在 run_queue 队列里的状态

运行状态:在 run_queue 队列里的状态

S——可中断睡眠状态:处于这个状态的进程因为等待某某事件的发生(比如等待 socket 连接、等待信号量),而被挂起

Z——zombie 状态(僵尸):父亲没有通过 wait 系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉

X——退出状态

利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?
ps -ef (system v 输出) ps -aux bsd 格式输出
ps -ef | grep pid

哪个命令专门用来查看后台任务? job -l

把后台任务调到前台执行使用什么命令?把停下的后台任务在后台执行起来用什么命令? fg

终止进程用什么命令? 带什么参数? kill -9 pid

怎么查看系统支持的所有信号? kill -l

搜索文件用什么命令? 格式是怎么样的? find dir -name “string*”

查看当前谁在使用该主机用什么命令? 查找自己所在的终端信息用什么命令?

w 用户名称;用户的机器名称或 tty 号;远程主机地址;用户登录系统的时间;空闲时间(作用不大);附加到 tty(终端)的进程所用的时间(JCPU 时间);当前进程所用时间(PCPU时间);用户当前正在使用的命令.
who 用户名、tty 号、时间日期、主机地址

who am i,id -un 命令用于显示登入的用户名

last 命令可用于显示特定用户登录系统的历史记录(last jason):用户名称;tty 设备号;历史登录时间日期;登出时间日期;总工作时间.
查找自己所在终端信息:who am i

使用什么命令查看用过的命令列表? history

使用什么命令查看磁盘使用空间? 空闲空间呢? df -hl
文件系统 容量 已用 可用 已用% 挂载点
Filesystem Size Used Avail Use% Mounted on /dev/hda2 45G 19G 24G 44% /
/dev/hda1 494M 19M 450M 4% /boot

使用什么命令查看网络是否连通? netstat

使用什么命令查看 ip 地址及接口信息? ifconfig

查看各类环境变量用什么命令?查看所有 env
查看某个,如 home: env $HOME

通过什么命令指定命令提示符?
\u 显示当前用户账号
\h 显示当前主机名
\W 只显示当前路径最后一个目录
\w 显示当前绝对路径(当前用户目录会以 ~代替)
PWD$ P W D 显 示 当 前 全 路 径 $ 显 示 命 令 行 ′ ’或者’#’符号
# :下达的第几个命令
\d :代表日期,格式为 weekday month date,例如:”Mon Aug 1”
\t :显示时间为 24 小时格式,如:HH:MM:SS \T :显示时间为 12 小时格式 \A :显示时间为 24 小时格式:HH:MM \v :BASH 的版本信息
如export PS1=’[\u@\h \w#]$ ‘

du 和 df 的定义,以及区别? du 显示目录或文件的大小
df 显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统。
(文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如 i 节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为 Meta Data。)
du 命令是用户级的程序,它不考虑 Meta Data,而 df 命令则查看文件系统的磁盘分配图并考虑 Meta Data。
df 命令获得真正的文件系统数据,而 du 命令只查看文件系统的部分情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值