- 进程管理
1、以记录型信号量为例介绍P、V操作:
struct semaphore{
int count ;
queueType queue;
};
P操作
wait (semaphore s)
{
s.count --;
If(count < 0)
{
阻塞该进程;
该进程插入等待队列:s.queue;
}
}
V操作
Signal(semaphore s)
{
s.count ++;
If(s.count <= 0)
{
从等待队列取出第一个进程P;
将P插入就绪队列;
}
}
代码要多写,写着写着就明白了
2、信号量的应用 P53下
实现进程同步
Semaphore N = 0;
P1()
{
...
S1;
V(N);
...
}
P2();
{
...
P(N);
S2;
...
}
实现进程互斥
Semaphore N = 1;
P1()
{
...
P(N);
P1的临界区代码;
V(N);
...
}
P2()
{
...
P(N);
P2的临界区代码;
V(N);
...
}
- 经典同步问题
- 生产者消费者问题 P55
Semaphore full = 0;
Semaphore empty = n;
Semaphore mutex = 1;
生产者关注空不空(empty),目的是将产品放入缓冲池
Produce()
{
Produce an item put in nextp;
P( empty );空不空
P( mutex );
将产品放入缓冲池;
V( mutex );
V( full ); 不是empty
}
消费者关注有没有(full),目的是将产品从缓冲池中取出
Consumer()
{
P( full );空不空
P( mutex );
取出产品;
V( mutex );
V( empty );
Consume the item in nextp;
}
注意事项见P55 下
- 读者写者问题
把第(1)个搞明白,剩下的迎刃而解
- 读者优先算法 P56下
三个信号量,两个是互斥信号量(rmutex,mutex),一个资源信号量(readcount)
Semaphore readcount = 1;
Semaphore rmutex = 1;
Semaphore mutex = 0;
读者:要求有读者(readcount>0)时写者不能访问,反之写者可访问;读者与读者之间不能同时访问
Reader()
{
while(true)
{
P(rmutex);
if(readcount == 0)
P(mutex);
Readcount++;
V(rmutex);
进行读操作
P(rmutex);
readcount--;
If(readcount == 0)
V(mutex);
V(rmutex);
}
}
Writer()
{
while(true)
{
P(mutex);
进行写操作;
V(mutex);
}
}
- 公平情况算法(按照到达顺序) P57下
主要变化就是读、写两个操作多了P(wmute);V(wmute);包在外面
Semaphore mutex = 1;
Semaphore rmutex = 1;
Semaphore wmutex = 1;
Semaphore readecount = 0;
Reader()
{
while(true)
{
P(wmutex);
P(rmutex);
if(readcount == 0)
P(mutex);
Readcount++;
V(rmutex);
V(wmutex);
进行读操作
P(rmutex);
readcount--;
If(readcount == 0)
V(mutex);
V(rmutex);
}
}
writer()
{
while(true){
P(wmutex);
P(mutex);
进行写操作
V(mutex);
V(wmuetx);
}
}
- 写者优先算法 P58下
将读、写操作里的while(true)删掉,wmutex改成readable,这里的wmutex用来互斥writercount,作用与rmutex同,此处写者与(1)处读者雷同
Semaphore mutex = 1;
Semaphore rmutex = 1;
Semaphore wmutex = 1;
Semaphore readable = 1;
Semaphore readcount = 0,writecount = 0;
Reader()
{
P(readable);
P(rmutex);
If(readcount == 0)
P(mutex);
Readcount++;
V(rmutex);
V(readable);
读者读;
P(rmutex)
Readcount--;
If(readcount == 0)
V(mutex);
V(rmutex);
}
Writer()
{
P(wmutex);
If(writercount == 0)
P(readable);
Writercount++;
V(wmutex);
P(mutex);
写操作
V(mutex);
P(wmutex)
Writercount--
If(writercount == 0)
V(readable)
V(wmutex);
}
- 哲学家进餐问题
- 减少资源竞争者(最多4个人进餐)
Semaphore chopsticks [5] = {1,1,1,1,1};
Semaphore eating = 4;
Void philopher (int i)
{
P(eating);
P( chopsticks[i]%5 );
P( chopsticks[i+1]%5 );
eating();
V( chopsticks[i+1]%5 );
V( chopsticks[i]%5 );
V(eating);
}
- 同时拿起筷子
Semaphore chopsticks[5] = {1,1,1,1,1};
sem phore mutex = 1;
Philosopher (int i)
{
While(true)
{
Thinking();
P(mutex);
P( chopsticks[i]%5 );
P( chopsticks[i+1]%5 );
V(mutex);
Eating();
V( chopsticks[i+1]%5 );
V( chopsticks[i]%5 );
}
}
(3)奇数先拿,偶数后拿
Semaphore chopsticks[5] = {1,1,1,1,1};
Pholiopher(int i)
{
While(true)
{
If( i%2 == 0)
{
P(Chopstick[i%5]);
P(chopstick[i%5+1])
Eating();
V(chopstick[i%5+1]);
V(chopstick[i%5]);
}
esle
{
P(Chopstick[i]%5);
P(chopstick[i+1]%5)
Eating();
V(chopstick[[i+1]%5);
V(chopstick[i]%5);
}
}
}
理发师问题
- 以理发师椅、等待椅为主线 P61
Int waiting = 0;
Semaphore mutex = 1;
Semaphore bchair = 1;
Semaphore wchair = 1;
Semaphore ready = finish = 1;
Barber() 理发师进程
{
While(true)
{
P(ready);
理发;
V(finish);
}
}
Customer()
{
P(mutex);
If(waiting < = n)
{
Waiting ++;
V(mutex);
}
Else
{
V(mutex);
离开;
}
P(wchair);
P(bchair);
V(wchair);
V(ready);
P(finish);
V(bchair);
P(mutex);
Waiting--;
V(mutex);
}
- 将理发椅、凳子、顾客数量统一为一个变量 P63
Int chairs = n + 1;
Semephore ready = 0;
Semaphore finish = 1;
Semaphore mutex = 1;
Barber()
{
While(true)
{
P(ready);
理发;
P(mutex);
Chairs ++;
V(mutex);
V(finish);
}
}
Customer()
{
P(mutex);
If(chairs > 0)
{
chairs--;
V(mutex);
V(ready);
P(finish);
}
Else
V(mutex);
}
- 内存管理
1、外部中断内部中断??
外部中断也称为外部硬件实时中断,他由来自CPU某一引脚上的信号引起;
内部中断也称软件指令中断,他是为了处理程序运行过程中发生的一些意外情况或调试程序而提供的中断
- 并行:同一时刻 多重处理
并发:同一时间段/时间间隔 多任务
3、
4、read函数从打开的设备或文件中读取数据。
#include <unistd.h>
ssize_t read (int fd, void *buf, size_t count);
ssize_t write (int fd, void * buf, size_t count);
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0
参数
count
是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)也可以返回负值-1(表示出错)。
read函数返回时,返回值说明了buf中前多少个字节是刚读上来的。有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有30个字节而请求读100个字节,则read返回30,下次read将返回0。
- 关于访问内存
A、 缺页中断访问几次内存,分别是什么时候访问
首先是执行指令访问内存时发现缺页,再调入内存,再继续执行中断的指令,访问页表,找到块号,再根据块号找到内存的数据,一共三次
B、没有缺页中断访问几次内存,分别是什么时候访问
两次;执行指令访问内存时访问页表,找到块号,再根据块号找到内存的数据
针对一般考研题目,一般将题中“访问内存时间”视为总的时间,除非题目中有特别说明每次访问内存时间是多少。