进程同步
进程同步的概念
进程同步也是进程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调它们的工作次序而等待、传递信息所产生的制约关系,进程间的直接制约关系来源于它们之间的合作。
由于进程切换并不完全受进程或操作系统的控制,所以在进程运行的任何时刻都可能发生进程切换。
在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有或仅仅占有一点必须资源)
临界资源指那些同一时间只能被一个进程所占有的资源,对临界资源的访问必须互斥
竞争条件:多个进程并发访问和操作统一数据且执行结果与访问发生的特定顺序有关。
故引入临界区问题的概念
临界区问题的解答必须满足三个要求:
- 互斥
- 前进(有空让进)
- 有限等待
解决临界区问题的方法
-
基于软件的解决方法
Peterson算法
-
基于硬件的解决方法
内存屏障、硬件指令(TestAndSet和CompareAndSwap指令)、原子变量
内存屏障是一条用于让内存中的变化让所有的处理器看到的指令
硬件指令:硬件确保该指令要么执行,要么不执行。保证其就算发生了中断也不会影响结果。
Peterson算法中进程 P i P_i Pi的结构
do{
flag[i]=true;
turn=j;
while(flag[j]&&turn==j)
;//无操作
critical section;//临界区
flag[i]=false;
remainder section;//剩余区
}while(true)
采用锁的临界区问题的解答
do{
acquire lock;//请求锁
critical section;//临界区
release lock;//释放锁
remainder section;//剩余区
}while(true)
TestAndSet指令的定义以及使用TestAndSet的互斥实现
- 定义
boolean TestAndSet(boolean *target)
{
boolean rv=*target;
*target=true;
return rv;
}
- 互斥实现
do{
while(TestAndSet(&lock))
;//无操作
critical section;//临界区
lock=false;
remainder section;//剩余区
}while(true)
Swap指令的定义以及使用Swap的互斥实现
- 定义
void Swap(boolean *a,boolean *b)
{
boolean temp=*a;
*a=*b;
*b=temp;
}
- 互斥实现
do{
key=true;
while(key==true)
Swap(&lock,&key);//无操作
critical section;//临界区
lock=false;
remainder section;//剩余区
}while(true)
CompareAndSwap指令的定义以及使用CompareAndSwap的互斥实现
- 定义
int CompareAndSwap(int *value, int expected,int new_value)
{
int temp=*value;
if(*value==expected)
*value=new_value;
return temp;
}
- 互斥实现
do{
while(CompareAndSwap(&lock,0,1)!=0)
;//无操作
critical section;//临界区
lock=false;
remainder section;//剩余区
}while(true)
使用TestAndSet/CompareAndSwap指令的有限等待互斥
do{
waiting[i]=true;
key=true;
while(waiting[i]&&key);
key=TestAndSet(&lock);//此处也可以用CompareAndSwap(&lock,0,1)代替
waiting[i]=false;
critical section;//临界区
j=(i+1)%n;
while((j!=i)&&!waiting[j])
j=(j+1)%n;
if(j==i)
lock=false;
else
waiting[j]=false;
remainder section;//剩余区
}while(true)
使用信号量的互斥实现
do{
wait(mutex);
critical section;//临界区
signal(mutex);
remainder section;//剩余区
}while(true)
信号量操作wait()的定义
wait(Semaphore *S){
S->value--;
if(S->value<0){
add this process to S->list;
block();
}
}
信号量操作signal()的定义
signal(Semaphore *S){
S->value++;
if(S->value<=0){
remove a process P from S->list;
wakeup(P);
}
}
有限缓冲问题中生产者和消费者进程结构
- 生产者进程
do{
// produce an item in nextp
wait(empty);
wait(mutex);
//add nextp to buffer
signal(mutex);
signal(full);
}while(true)
- 消费者进程
do{
wait(full);
wait(mutex);
// remove an item from buffer to nextc
signal(mutex);
signal(empty);
// consume the item in nextc
}while(true)
读者写者问题中写者和读者进程结构
- 写者进程
do{
wait(wrt);
// 写操作
signal(wrt);
}while(true)
- 读者进程
do{
wait(mutex)
readcount++;
if(readcount==1)
wait(wrt);
signal(mutex);
//读操作
wait(mutex)
readcount--;
if(readcount==0)
signal(wrt);
signal(mutex);
}while(true)
Solaris同步:适应互斥、条件变量、信号量、读写锁和十字转门
Windows XP同步:互斥锁、信号量、事件、定时器、自旋锁
事件是一个同步机制,其使用与条件变量相似,即当所需条件出现时会通知等待线程。
Linux同步:自旋锁和信号量