互斥:一个公共资源不能被多个程序使用,由于早餐店是公共资源,两个队伍不能同时使用早餐店。
同步:由于早餐店只存在一个篮子,所以煎饼果子与鸡蛋灌饼应叫交替运行。只有老板或者老板娘将物品放入篮子中,两只对于才可以拿走货物。
var items = 0 ,window_size = 1 ,mutex =1;
//如果缓冲区为1则不需要互斥信号量
var Chinese hamburger= 0,Eggs filled pie = 0;
//煎饼果子,鸡蛋灌饼
producer1()
{
while(1)
{
p(Chinese hamburger);
p(mutex);
/*煎饼果子放入篮子,临界区*/
v(mutex);
v(Chinese hamburger);
}
}producer2()
{
while(1)
{
p(Eggs filled pie);
p(mutex);
/*鸡蛋灌饼放入篮子,临界区*/
v(mutex);
v(Eggs filled pie);
}
}customer1()
{
while(1)
{
p(Eggs filled pie);
p(mutex);
/*鸡蛋灌饼拿走,临界区*/
v(mutex);
v(Eggs filled pie);
}
}customer2()
{
while(1)
{
p(Chinese hamburger);
p(mutex);
/*煎饼果子拿走,临界区*/
v(mutex);
v(Chinese hamburger);
}
}互斥:题目中的公共资源为打印机,即打印机被所有顾客进程所共享,所以设置互斥量来实现互斥。
同步:由于理发师只有一个,所以只有在当前顾客将打印机置为睡眠状态,下一个顾客唤醒打印机才能使用。
var waiting = 0 ;
var waiting_area;
semaphore customers = 0 , printer = 0,mutex =1;
void printer()
{
while(1){
p(customers);//wait+1
p(mutex);
//进入临界区
waiting--;
v(printer);
v(mutex);
print();
}
}
void customer()
{
p(mutex);//进入临界区
if(waiting < waiting area){
waiting++;
v(customers);//唤醒打印机
v(mutex);//退出临界区
p(printer);//顾客等待
get_wait_area();
}else{
v(mutex);//直接离开
}
}使用AND信号量机制解决死锁问题,末尾哲学家进入临界区之后,才将筷子分配给他,然后进餐,否则不给他资源。使用全局互斥量mutex来限制全部的临界区的资源,当有哲学家拿起筷子的时候,将所有的资源锁住,放下筷子的时候释放资源。
mutex的初始化
在.h中
pthread_mutex_t mutex[1];main.c中
pthread_mutex_init(&mutex[0], NULL);philosopher.c中
void *philosopher(void *philosopherNumber) {
int i = (int)philosopherNumber;//int i = *(int *)arg;
//int left = i;
//int right = (i+1)%NUMBER_OF_PHILOSOPHERS;
while (1) {
/*Your code here*/
//printf("unimplemented yet\n");
think(i);//思考
pthread_mutex_lock(&mutex[0]);//进入互斥
pickUp(i);//拿起筷子
pthread_mutex_unlock(&mutex[0]);//释放互斥
eat(i);//吃
putDown(i);//放下筷子
//exit(1);
}
}伪代码
void philosopher (void* arg) {
while (1) {
think();
hungry();
pthread_mutex_lock(&chopsticks[left]);
pthread_mutex_lock(&chopsticks[right]);
eat();
pthread_mutex_unlock(&chopsticks[left]);
pthread_mutex_unlock(&chopsticks[right]);
}
}在实现对于筷子的互斥时,筷子的初始化为
for (i = 0; i < NUMBER_OF_PHILOSOPHERS; ++i) {
pthread_mutex_init(&chopsticks[i], NULL);
}所以在拿起和放下筷子的时候的信号量为同意对信号量:
void pickUp(int philosopherNumber) {
// request chopsticks
/*Your code here*/
int left = philosopherNumber;//左筷子为本身
int right = (philosopherNumber + 1) % 5;//有筷子为+1取模
pthread_mutex_lock(&chopsticks[right]);//锁住筷子
pthread_mutex_lock(&chopsticks[left]);
printf("Philosopher %d pick up %d and %d chopsticks\n", philosopherNumber,left,right);
}void putDown(int philosopherNumber) {
// release chopsticks
/*Your code here*/
int left = philosopherNumber;
int right = (philosopherNumber + 1) % 5;
pthread_mutex_unlock(&chopsticks[right]);//释放筷子
pthread_mutex_unlock(&chopsticks[left]);
printf("Philosopher %d pick down %d and %d chopsticks\n", philosopherNumber,left,right);
}linux的运行截图。