一、进程与线程
进程和线程的相互比较:
(1)调度:进程是资源拥有的基本单位,线程是独立调度的基本单位(CPU执行的基本单位)
(2)并发性:进程跟线程都可以并发
(3)地址空间:进程的地址空间是相互独立的,同一进程的各个线程之间共享进程的资源
(4)通信方面:进程间通信需要进程同步和互斥手段的辅助,而线程之间可以直接读写进程数据段(如全局变量)来进行通信
二、处理机调度
三、进程同步
PV操作详解:
typedef struct{
int value;//代表资源数目
struct process *L;//链接所有等待该资源的进程
}semaphore;
void wait(semaphore S)//相当于申请资源
{
S.value--;
if(S.value<0)
{
把这个进程添加到等待链表;
block(S.L);//进行自我阻碍,放弃处理机,并插到该类资源的等待队列S.L中
}
}
void signal(semaphore S){//相当于释放资源
S.value++;
if(S.value<=0)
{
从等待链表中摘除一个进程;
wakeup(P);//将S.L中的第一个等待进程唤醒
}
}
//生产者-消费者问题
问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能将消息放入到缓冲区,
否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息
,或者一个消费者取出消息
semaphore mutex=1;//临界区互斥信号量
semaphore empty=n;//空闲缓冲区
semaphore full=0;//缓冲区初始化为空
producer(){
while(1)
{
生产一个数据;
P(empty);//P(empty)必须放在P(mutex)之前,若相反,假如empty=0,当生产者运行时,生产者和消费之都会阻塞,陷入无休止的等待
P(mutex);
将数据放入缓冲区;
V(mutex);
P(full);
}
}
consumer(){
while(1)
{
p(full);
p(mutex);
从缓冲区取数据;
V(mutex);
V(empty);
消费数据;
}
}
四、死锁
银行家算法核心思想:
保证系统现有的资源大于任何进程运行还需要的资源,从而找到一个安全序列,保证进程之间不会发生死锁