进程互斥访问&同步问题综合

1窗口n客人叫号

面包师有很多面包,由n名销售人员卖。每个客人进店后取号,并等待叫号。当一名销售人员空闲,就叫下一个号。

n个销售【服务窗口】,n个客人
int waitnum=0;//取号值
int servernum=0;//叫号值
semaphore mutex_waitnum=1,mutex_servernum=1;//用来保证修改num过程是原子性

//mutex_waitnum和mutex_servernum只是锁
//waitnum作为状态变量
customer{
	while(1){
        P(mutex_waitnum);
        //取号
        waitnum+=1;
        V(mutex_waitnum);
    }
}

server{
	while(1){
        P(mutex_servernum);
        if(waitnum<servernum){
            servernum+=1;
        }
        V(mutex_servernum);
    }
}

//方法2:完全使用PV操作
semaphore mutex=1;//锁:锁取号机
customer{
    P(mutex);
    取号
    V(mutex);
    V(customer);//告诉服务人员,来人了
    P(server);//等待服务
    被服务函数
}

server{
    P(customer);//消耗一个客人
    V(server);//提供服务
    服务函数
}

1窗口n客人M椅子,人会离开

理发店里面一位理发师,一把理发椅子和n个等待时椅子。若没有客人,理发师在理发椅子上睡觉。若有客人,客人要叫醒理发师,若理发师在理发又有客人来,若椅子有空,客人在椅子上等待,椅子不空就离开。使用PV操作

本题中,椅子不空就离开。说明不是进程不是一直等待下去,不能直接用P操作,因为P操作会一直等待。需要用状态变量+锁的方式完成
int wait=0,chair=n;
semaphore mutex_wait=1;//锁
semaphore server=0;//表示需要服务数
semaphore customer=0;//表示客人数量

//和第一题方法2相似
customer{
	P(mutex_wait);
	if(wait<chair){
		wait+=1;
		V(customer);//告诉服务人员,来人了
		V(mutex);
		P(server);//等待服务
        被理发函数
	}
	else{
		V(mutex_wait);
	}
}

barber{
    P(customer);//如果有客人就提供服务,没有就睡觉
    P(mutex_wait);
    wait-=1;
    V(server);//理发师醒了
    V(mutex_wait);
    理发函数
}

1窗口n客人M椅子,人不离开

银行提供一个服务窗口和10个等待座位。客人到达银行时,若有空位,则到取号机拿号并坐下等待。否则就一直等待空座位再拿号。取号机每次仅允许一个人使用。营业员空闲时,叫号一个客人并服务。

本题中,椅子不空就等待,可以使用PV
semaphore chair=10;//固定资源
semaphore mutex=1;//锁
semaphore customer=0;
semaphore server=0;

customer{
	P(chair);//有椅子就拿号,没椅子就等。不像第二题会走
	P(mutex);//叫号机上锁
	取号函数
	V(mutex);
    V(customer);//告诉服务人员,来人了
    P(server);//等待服务
    被服务函数
}

server{
    P(customer);//消耗一个客人
    V(chair);//空出一个椅子
    V(server);//提供服务
    服务函数
}

双资源生产者问题

小和尚,老和尚若干。有一个水缸,只能小和尚提水给老和尚用。水缸可以容10桶水,水取自同一个水井。水井每次只能由一桶水,一共有3个水桶。水缸一次只能入一桶水。

semaphore mutex_shaft=1;//水井
semaphore mutex_tank=1;//水缸
semaphore bucket=3;//资源
semaphore tank_empty=10;//经典生产者和消费者的条件变量
semaphore tank_full=0;

老{
    P(tank_full);
    P(bucket);
    P(mutex_tank);
    取水
    V(mutex_tank);
    V(bucket);
    V(tank_empty);//提醒生产者生产
}

小{
	P(tank_empty);
    P(bucket);
    P(mutex_shaft);
    从水井打水
    V(mutex_shaft);
    //再向水缸放水
    P(mutex_tank);
    放水
    V(mutex_tank);
    V(bucket);
    V(tank_full);//提醒消费者消费
}

多进程同步问题

三个合作进程P1,P2,P3。者通过同一个设备输入各自的数据a,b,c。输入设备互斥使用。a为第一个输入必须由P1读取。b为第二个输入必须由P2读取。c为第二个输入必须由P3读取。然后进行以下运算

P1:x=a+b;

P2:y=a*b;

P3:z=y+c-a;

最后,由P1通过打印机将x,y,z打印出来。

因为规定了P1先取a,P2再取b,P3最后取C。设置fetch_a=1;fetch_b=0;fetch_c=0;表示a可以取

P1需要等待P2读取b,则有个信号量b_done

P3需要等待P2计算出y,则有个信号量y_done

P1最后需要等待P3计算出z,则有个信号量z_done

semaphore fetch_a=1;
semaphore fetch_b=1;
semaphore fetch_c=1;

P1{
	P(fetch_a);
	取a数据
	V(fetch_b);//允许P2读取b
	P(b_done);//在P2得到b之前,P1要等待
	x=a+b;
	P(z_done);//在P3得到z之前,P1要等
	打印x,y,z//因为z也需要y,所以P1不用等y
}

P2{
	P(fetch_b);
	取b数据
	V(fetch_c);//允许P3读取c
	y=a*b;
	V(y_done);//唤醒等待y的进程
}

P3{
	P(fetch_c);
	取c数据
	P(y_done);//等待y
	z=y+c-a;
	V(z_done);//唤醒等待z的进程
}

未完……