第6章
6.1
代码划分
do{
flag[i]=true;
while(flag[j]){
if(turn==j){
flag[i]=false;
while(turn==j) //ES
;
flag[i]=true;
}
}
// CS
turn=j;
flag[i]=false; //EXS
//RS;
}while(TRUE);
1 互斥条件:
假设此时进程i在CS里面,进程j在ES里面,那么此时的flag[i]=1,因此j进程会被阻塞在while循环里面。如果进程j在CS里面,i同样也会被阻塞,从而保证了互斥条件。
2 前进条件:
当进程i执行完EXS代码时,如果此时进程j刚开始执行第一行代码,此时进程j就会跳过循环,直接进入CS里面,如果此时进程j已经进入while循环,则会跳出循环,进入CS里面。
3 有限等待:
当进程i执行完EXS代码时,如果进程j在RS里面,那么由于此时turn=j,因此进程i就会陷入内层while循环,直到进程j执行完EXS代码,对于此时进程j在ES里面的情况,第二个条件已经讨论了。因此两个进程的执行顺序会是:Pi,Pj,Pi,Pj…. 或者是Pj,Pi,Pj,Pi….
6.2
互斥条件:
只有当没有其它进程在临界区中有设置的标识变量时,当前进程才可以进入临界区里面,因此保证了互斥。
前进:
当多个进程同时在CS中设置标识变量,然后检查是否有其它进程在CS中设置标识变量。此时,所有的进程之间存在竞争。只有那些序号接近turn的进程才有机会进入临界区域内并且设置标识,随后这些进程之间存在竞争,然后重新启动进入临界区域内的进程。每次迭代时,CS中设置的标识越来越接近turn,只有进程i才能进入CS,并且在turn与i之间的进程不能进入CS。
有限等待条件:
进程i打算进入临界区域时,它的标志不再为空闲,只有序号在turn和i之间的进程才能进入临界区域。并且turn越来越接近i,最后turn与i之间的进程为空,或者turn变为i。因此进程i可以进入临界区域内。
6.4
自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,但是自旋锁一直占用CPU,他在未获得锁的情况下,一直运行--自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。当前处理器被占用,并且没有其它处理器闲置时,其它进程不能够得到提供打破当前进程自旋锁的条件的机会。但是在多处理器上,我们可以在其它处理器上为当前进程提供该条件。
6.7
do {
waiting[i ]=TRUE;
key=TRUE;
while(waiting[i]&&key)
key=Swap(&lock,&key);
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);
6.10
int guard= 0;
semaphore value=0 ;
wait(){
while (TestAndset(&guard)==1);
if (value==0){
queue.push(process);
value=0;
guard=0;
}
e1se{
value--;
guard=0;
}
}
signal(){
while(TestAndset(&guard)==1);
if(value==0&&!queue.empty()){
process=queue.front() ;
queue.pop( );
}
e1se
va1ue++;
guard=0;
}
6.11
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iostream>
#define n 5
using namespace std;
sem_t mutex,wmutex;
int custem_count=0;
bool barber=0;
void *Barber(void *id){
sem_wait(&mutex);
custem_count++;
if(custem_count>n){
cout<<*((string *)id)<<":已经离去!!"<<endl;
custem_count--;
sem_post(&mutex);
pthread_exit(0);
}
sem_post(&mutex);
sem_wait(&wmutex);
if(!barber){
barber=1;
cout<<*((string *)id)<<":将理发师摇醒开始理发!!"<<endl;
}
else{
cout<<*((string *)id)<<":正在接受理发!!"<<endl;
}
sem_post(&wmutex);
sem_wait(&mutex);
custem_count--;
if(custem_count==0){
cout<<"--------理发师睡觉中!!!----------"<<endl;
barber=0;
}
sem_post(&mutex);
}
int main() {
pthread_t tid[9];
string custem[9]={"顾客1","顾客2","顾客3","顾客4",
"顾客5","顾客6","顾客7","顾客8",
"顾客9"};
sem_init(&mutex,0,1);
sem_init(&wmutex,0,1);
for(int x=0;x<9;x++)
pthread_create(&tid[x],NULL,Barber,&custem[x]);
for(int x=0;x<9;x++){
pthread_join(tid[x],NULL);
}
}
6.13
moniter buff{
int item[max];
int num_item=0;
condition full,empty;
void produce(int v){
while (num_item==max) full.wait() ;
item [num_item++]=v;
empty.signal();
}
int consume(){
int retval;
while(num_item==0) empty.wait();
retval=items[--num_item] ;
full.signal();
return retval;
}
6.23
a
可用资源的数量 available_resources与竞争条件有关。
b
else{
available_resources-=count; //竞争条件有关
return 0;
}
int increase_count{
available_resources+=count; //竞争条件有关
return 0;
}
c
#define MAX_RESOURCES 5
int available_resources = MAX_RESOURCES;
int decrease_count(int count){
if(available_resources < count)
return -1;
else{
wait(mutex);
available_resources-=count;
signal(mutex);
return 0;
}
}
int increase_count{
wait(mutex);
available_resources+=count;
signal(mutex);
return 0;
}