@3013216027
2016-01-28T13:18:05.000000Z
字数 8867
阅读 1910
os2015
enter_regine:
move register, 1H
xchg register, lock
cmp register, 0H
jnz enter_regine
ret
leave_regine:
move lock, 0H
ret
类型 | 可转义字符 |
---|---|
单引号 | 硬转义,内部所有通配符和shell元字符均被关闭 |
双引号 | 软转义,内部可以使用$和` |
反斜线\ | 转义,能且仅能转义后面紧跟的一个字符 |
参数 | 功能 |
---|---|
-a , -o |
逻辑与,或 |
(直接字符串) 或-n , -z , = , != |
字符串长度非0,为0,相等,不等 |
-ge , -gt , -eq , -ne , -lt , le |
整数≥,>,=,≠,<,≤ |
-d , -e , -s , -r , -w , -x |
文件为目录,存在,非空,可读,可写,可执行 |
一个进程包含3部分:
进程控制块(Process Control Block, PCB):记录了进程的描述信息和控制信息。系统创建进程时,为每个进程设置一个PCB,进程被撤销时系统收回其PCB。PCB是一个进程存在的唯一标志。其中包含了:
等信息。
进程的创建
fork()
vfork()
(kernel call 2):创建一个子进程execl()
execv()
execle()
execve()
execlp()
execvp()
: 执行一个指定的文件(如/bin/ls)wait()
waitpid()
: 等待进程状态改变exit()
(lib call 3): 正常终止进程system()
(lib call 3): 执行一个shell命令ls -l
)时,先fork, 再exec,完毕后exit 进程的生命周期:
进程的结束时机
读者优先的读者-写者问题
semaphore count_mutex = 1; /* 读者计数器互斥访问 */
semaphore db_mutex = 1; /* 数据库互斥访问 */
int count = 0; /* 读者计数 */
void
reader()
{
/* enter */
P(count_mutex);
if (count == 0) P(db_mutex);
count = count + 1;
V(count_mutex);
read_data();
/* leave */
P(count_mutex);
count = count - 1;
if (count == 0) V(db_mutex);
V(count_mutex);
}
void
writer()
{
/* enter */
P(db_mutex);
write_data();
/* leave */
V(db_mutex);
}
semaphore db_mutex = 1; /* 数据库互斥访问 */
semaphore creader_mutex = 1; /* 读者计数器互斥访问 */
semaphore readable = 1; /* 可读信号量 */
int creader = 0;
void
reader()
{
/* enter */
P(readable);
P(creader_mutex);
if (creader == 0) P(db_mutex);
creader = creader + 1;
V(creader_mutex);
V(readable);
read_data();
/* leave */
P(creader_mutex);
creader = creader - 1;
if (creader == 0) V(db_mutex);
V(creader_mutex);
}
void
writer()
{
P(write_mutex);
P(mutex);
read_data();
V(mutex);
V(write_mutex);
}
semaphore creader_mutex = 1;
semaphore cwriter_mutex = 1;
semaphore reading = 1;
semaphore writing = 1;
int creader = 0;
int cwriter = 0;
void
reader()
{
P(reading);
P(creader_mutex);
if (creader == 0) P(writing);
creader = creader + 1;
V(creader_mutex);
V(reading);
read_data();
P(creader_mutex);
creader = creader - 1;
if (creader == 0) V(writing);
V(creader_mutex);
}
void
writer()
{
P(cwriter_mutex);
if (cwriter == 0) P(reading);
cwriter = cwriter + 1;
V(cwriter_mutex);
P(writing);
write_data();
V(writing);
P(cwriter_mutex);
cwriter = cwriter - 1;
if (cwriter == 0) V(reading);
V(cwriter_mutex);
}
pthread_create
: 创建线程pthread_exit
: 线程退出pthread_join
: 等待某线程退出pthread_yield
: 线程主动释放CPU资源
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define MAX 10
void* say_hello(void* tid) {
printf("hello from %d\n", *(int*)tid);
pthread_exit(NULL);
return NULL;
}
int main() {
pthread_t threads[MAX];
int ids[MAX];
int status, i;
for (i = 0; i < MAX; ++i) {
printf("Create thread %d\n", i);
ids[i] = i;
status = pthread_create(threads + i, NULL, say_hello, (void*)(ids + i));
if (status != 0) {
printf("error occur when create thread, with ret %d\n", status);
exit(-1);
}
}
return 0;
}
条件 | 预防方法 |
---|---|
互斥 | 统一使用假脱机 |
占有和等待 | 在开始就请求全部资源 |
不可抢占 | 抢占资源 |
环路等待 | 资源按序访问 |
最近未使用置换算法 NRU
R
表示被访问过,M
表示被修改过。分为4类:类编号 | RM标志位 | 状态 |
---|---|---|
0 | 00 | 未被访问,未修改过 |
1 | 01 | 未被访问,修改过 |
2 | 10 | 被访问过,未修改 |
3 | 11 | 被访问过,修改过 |
R
位在每个时钟中断定期清除,再被访问又置1,需要置换时每次从类编号尽量小的类中任选页面置换。置换时若M
为1则写入磁盘,否则直接丢弃。 R
位,队头页面若R
为0,则直接丢掉,否则R
置0放入队尾,并继续查找可置换页面R
为0则直接用新页面替换它,否则R
清零,指针前移继续查找n x n
矩阵,初始化全0,访问页框k
时,置第k
行全1,再置第k
列全0。每次置换对应行代表的二进制最小的页面R
位加到计数器上。缺点是不能忘记之前的历史访问信息R
加到最高位上。 1TB
崭新的硬盘(仅1个分区,大小1TB),LVM是这么做的,首先把整个硬盘切成每份4M的若干小块(可以想象成积木= =),如1TB = 1024GB = 1024*1024MB = 256*1024小块 = 262144小块
。然后这262144块可以随意地组合拼出所需大小(当然,必须为4M的整数倍),如分成两组(128*1024块 + 128*1024块),成为2个512G的分区,在用户看来,就有了2个每个512G的盘;或者分为(64*1024块 + 192*1024块),成为2个大小分别为256G和768G的分区;或者分成3组(64*1024块 + 64*1024块 + 128*1024块),成为3个大小分别为256G、256G和512G的分区。512GB
(1个分区,512G)和1TB
(1个分区,大小1TB)的硬盘,类似地,LVM把它们都分成每块4M的小块。共128*1024块 + 256*1024块 = 384*1024块
,然后LVM有两种选择,第一种是第一块硬盘单独考虑,第二块也单独考虑,第二块可以和上面一样随便处理,第一块也可以随意分;第二种选择是两块硬盘一起拿来分,混起来分,打乱了分!总之这384*1024块就和之前一样,可以拿来随意地分啊分,甚至可以分成384*1024
份,每份1块!这样就有了393216个分区,嚯!如果有个1PB的硬盘,那么最多大概可以分出近400万个分区,如果windows也资瓷这个东西,泥打开“我的电脑”后可以就可以欣喜地看到C盘、D盘、E盘、...、Z盘、AA盘、AB盘、AC盘、ZHENG盘、DONG盘、JIAN盘= =1TB(两个分区一个128G一个896G)
,LVM会把它们当做两个硬盘,大小分别是128G和896G来处理,就和上面的(512G+1T双硬盘)类似了。事实上,LVM才不管有几个物理硬盘,它只看得到原来共有几个分区。3+3+5
、1+1+9
这样的“小组”,然后每个小组内的所有小块(PE)再拼凑出一个个(逻辑)分区。前述的每个“小组”都是一个卷组(Volumn Group, VG),意思就是“几个卷拼成一个小组”。读取数据花费时间主要包括:
先来先服务 FCFS, First Come First Serve
最短寻道优先 SSF, Shortest Seek First
电梯算法 elevator, SCAN
循环扫描 C-SCAN, Circular SCAN
LOOK & C-LOOK
进程-死锁
内存-概览
内存-页面置换
Intel-x86
存储-存储
设备-设备