您的当前位置:首页正文

C语言模拟信号量解决同步、互斥问题

2024-12-12 来源:个人技术集锦

信号量实现进程同步

#include<stdio.h>

typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L; //阻塞队列
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void P1(int *n) 
{
	printf("process P1!\n");
	printf("Access code.\n");
	V(n);
}

void P2(int *n)
{
	printf("process P2!\n");
	P(n);
	printf("Access code.\n");
}

int main()
{
	semaphore n=0;
	P1(&n);
	P2(&n);
	return 0;
}

信号量实现进程互斥

#include<stdio.h>

typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void P1(int *n) 
{
	printf("process P1!\n");
	P(n);
	printf("Access critical code.\n");
	V(n);
}

void P2(int *n)
{
	printf("process P2!\n");
	P(n);
	printf("Access critical code.\n");
	V(n);
}

int main()
{
	semaphore n=1;
	P1(&n);
	P2(&n);
	return 0;
}

生产者消费者问题

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void producer(int *mutex,int *full,int *empty) 
{
	printf("process of producer!\n");
	while(1){
		printf("produce an item in nextp.\n");//生产数据
		P(empty);  //获得空闲缓冲区单元 ,先获得资源
		P(mutex);  //再获得进入临界区的资格
		printf("add nextp to buffer.\n"); //将数据放入缓冲区
		V(mutex); //离开临界区
		V(full); //缓冲区满
		getch();
	}
}

void consumer(int *mutex,int *full,int *empty) 
{
	printf("process of consumer!\n");
	while(1){

		P(full);  //获得满缓冲区单元 ,先获得资源
		P(mutex);  //再获得进入临界区的资格
		printf("remove an item form buffer.\n"); //从缓冲区取走数据
		V(mutex); //离开临界区
		V(empty); //缓冲区空
		printf("consumer the item.\n");//消费数据
		getch();
	}
}

int main()
{
	semaphore mutex=1;  //临界区互斥信号量
	semaphore empty=3;  //空闲缓冲区,资源信号量
	semaphore full=0;    //缓冲区初始化为空,资源信号量
	producer(&mutex,&full,&empty);
	consumer(&mutex,&full,&empty);
	return 0;
}

读者写者问题,读进程优先

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void writer(int *rw) 
{
	printf("process of writer!\n");
	while(1){
		P(rw);  //互斥访问共享文件爱你
		printf("Wrting...\n");
		V(rw);  //释放共享文件
		getch();
	}
}

void reader(int *mutex,int *rw,int *count) 
{
	printf("process of reader!\n");
	while(1){
		P(mutex); //互斥访问count变量
		if((*count)==0) //当第一个读进程读共享文件时,阻止写进程
			P(rw);
		(*count)++; //读者计数加1
		V(mutex); // 释放互斥变量count
		printf("Reading...\n");
		P(mutex); //互斥访问count变量
		(*count)--; //读者计数减1
		if((*count)==0) //当最后一个读进程读完共享文件
			V(rw); //允许写进程写
		V(mutex);  //释放互斥变量count
		getch();
	}
}
int main()
{
	int count=3;  //用于记录当前的读者数量
	semaphore mutex=1; //用于保护更新count变量时的互斥
	semaphore rw=1; // 用于保证读者和写者互斥地访问文件
	writer(&rw);
	reader(&mutex,&rw,&count);
	return 0;
}

读者写者问题,写进程优先

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void writer(int *w,int *rw) 
{
	printf("process of writer!\n");
	while(1){
		P(w);  //在无写进程时请求进入
		P(rw); //互斥访问共享文件
		printf("Writing...\n");
		V(rw); //释放共享文件
		V(w);  //恢复对共享文件的访问
		getch();
	}
}

void reader(int *mutex,int *rw,int *count,int *w) 
{
	printf("process of reader!\n");
	while(1){
		P(w); //在无写进程时请求进入
		P(mutex);  //互斥访问count变量
		if((*count)==0)  //当第一个读进程读共享变量时,阻止写进程写
			P(rw);
		(*count)++;  //读者数量加1
		V(mutex);  //释放互斥变量count
		V(w);    //恢复对共享文件的访问
		printf("Reading...\n");
		P(mutex); //互斥访问count变量
		(*count)--;
		if((*count)==0)//当最后一个读进程读完共享文件 允许写进程写
			V(rw);
		V(mutex);
		getch();
	}
}
int main()
{
	int count=3;  //用于记录当前的读者数量
	semaphore mutex=1; //用于保护更新count变量时的互斥
	semaphore rw=1; // 用于保证读者和写者互斥地访问文件
	semaphore w=1; // 用于实现写优先
	writer(&w,&rw);
	reader(&mutex,&rw,&count,&w);
	return 0;
}



哲学家就餐问题

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}

void P1(int *mutex,int chopstick[])
{
	do{
		P(mutex); //取筷子前获得互斥变量
		P(&chopstick[1]);//取左筷子
		P(&chopstick[(1+1)%5]); //取右筷子
		V(mutex); //释放取筷子信号量
		printf("Eating...\n");
		V(&chopstick[1]);//放回左边筷子
		V(&chopstick[(1+1)%5]); //放回右边筷子
		printf("Thinking...\n");
		getch();
	}while(1);
}

void P2(int *mutex,int chopstick[])
{
	do{
		P(mutex); //取筷子前获得互斥变量
		P(&chopstick[2]);//取左筷子
		P(&chopstick[(2+1)%5]); //取右筷子
		V(mutex); //释放取筷子信号量
		printf("Eating...\n");
		V(&chopstick[2]);//放回左边筷子
		V(&chopstick[(2+1)%5]); //放回右边筷子
		printf("Thinking...\n");
		getch();
	}while(1);
}

// five phisolopher represents five process...

int main()
{
	semaphore chopstick[5]={1,1,1,1,1};
	semaphore mutex=1;  //设置取筷子的信号量
	P1(&mutex,chopstick);
	P2(&mutex,chopstick);
	return 0;
}

void P1(int *mutex,int chopstick[])
{
	do{
		P(&chopstick[1]);//取左筷子
		P(&chopstick[(1+1)%5]); //取右筷子
		printf("Eating...\n");
		V(&chopstick[1]);//放回左边筷子
		V(&chopstick[(1+1)%5]); //放回右边筷子
		printf("Thinking...\n");
		getch();
	}while(1);
}

以上算法存在以下问题:当五个哲学家都想要进餐,分别拿起他们左边的筷子的时候(都恰好执行完wait(chopstick[i];)筷子已经被拿光了,等待他们再拿起右边筷子的时候(执行wait(chopstick[(i+1)%5];)就完全被阻塞了,这就出现了死锁。为了防止死锁发生,需要对算法施加一些限制,比如至多允许四个哲学家同时进餐;仅当一个哲学家左右两边的筷子都可用时才允许他们抓起筷子;对哲学家顺序编号,要求奇数号哲学家先抓起左筷子,然后再抓起他右边的筷子,而偶数哲学家恰好相反。

显示全文