【0403】互斥与同步2

互斥与同步

信号量

信号量:只能进行三种操作,即初始化,递减和增加,这三种操作都是原子操作,递减相当于阻塞一个进程,递增相当于解除一个进程的阻塞。

互斥量:类似二元信号量,关键区别在于为其加锁(置0)和解锁(置1)的进程必须为同一个进程

条件变量:用来阻塞进程或线程,知道特定的条件为真

管程:

事件标志:

信箱/信息:

自旋锁:

强信号量:使用先进先出的规则释放进程

弱信号量:没有规定进程从队列移除的信号量

非二元信号量也成为计数信号量,一般信号量

const int n=process_number;
semaphore s=1;
void P(i)
{
	while(true)
	{
		semWait(s);
		/*临界区*/;
		semSignal(s);
		/*其余部分*/}
}
void main()
{
	Parbegin(P(1),P(2),...P(n));
}

生产者/消费者问题

缓冲区无限

producer;
while(true)
{
	/*生产v*/;
	b[in]=v;
	in++;
}
consumer;
while(true)
{
	while(in<=out)
		/*不做任何事*/;
	w=b[out];
	out++;
	/*消费w*/;
}

二元信号量(无限缓冲区)

int n;//n=in-out
binary_semaphore s=1;//判断临界区是否为空
binary_semaphore delay=0;//同步缓冲区。告知对方缓冲区情况
void producer()
{
	while(true)
	{
		produce();
		semWaitB(s);
		append();
		n++;
		if(n==1)
			semSignalB(delay);
		semSignalB(s);
	}
}
void consumer()
{
	semWait(delay);
	while(true)
	{
		semWaitB(s);
		take();
		n--;
		semSignalB(s);//这个时候生产者可以进入缓冲区
		consume();
		if(n==0)semWaitB(delay);//会发生死锁
	}
}
void main()
{
	n=0;
	parbegin(producer,consumer);
}

计数信号量(缓冲区无限)

semaphore n=0;//控制“超前消费”,同步信号量
semaphore s=1;//控制进入临界区
void produce()
{
	while(true)
	{
		produce();
		semWait(s);
		append();
		semSignal(s);
		semSignal(n);
	}
}
void consumer()
{
	while(true)
	{
		semWait(n);//先同步信号量
		semWait(s);
		take();
		semSignal(s);
		consume();
	}
}

缓冲区有限

producer;
while(true)
{
	/*生产v*/;
	while()
	b[in]=v;
	in++;
}
consumer;
while(true)
{
	while(in<=out)
		/*不做任何事*/;
	w=b[out];
	out++;
	/*消费w*/;
}

计数信号量

semaphore n=0;//控制“超前消费”,同步信号量
semaphore s=1;//控制进入临界区,异步信号量通常置为1
semaphore e=sizeofbuffer;
void produce()
{
	while(true)
	{
		produce();
		semWait(e);
		semWait(s);
		append();
		semSignal(s);
		semSignal(n);
	}
}
void consumer()
{
	while(true)
	{
		semWait(n);//先同步信号量
		semWait(s);
		take();
		semSignal(s);
		semSignal(e);
		consume();
	}
}

读者/写者问题

多个读者可以同时读取数据,多个写者不能同时写数据。除了第一个读者后续读者不需要申请进入临界区可以直接进入

读者:
while(true)
{
	P(mutex);//读者进入,申请修改读者数量
		readcount++;
		if(readcount==1)
			P(w);
	V(mutex);
	P(mutex);//读者离开,,申请修改读者数量
		readcount--;
		if(readcount==0)
			V(w);
	V(mutex);
}
写者://可能会产生饥饿
while(true)
{
	P(w);V(w);
}
解决办法一:写者优先方案一
相当于排队时写者可以一起连续排,读者不行
读者:
while(true)
{
    P(S);
	P(mutex);//读者进入,申请修改读者数量
		readcount++;
		if(readcount==1)
			P(w);
	V(mutex);
	V(S);
	读;
	P(mutex);//读者离开,,申请修改读者数量
		readcount--;
		if(readcount==0)
			V(w);
	V(mutex);
}
写者:
while(true)
{
	P(wmutex);//写者进入,申请修改写者数量
		writecount++;
		if(writecount==1)
			P(S);
	V(wmutex);
	P(w);V(w);
	P(wmutex);//写者离开,申请修改写者数量
		writecount--;
		if(writecount==0)
			V(S);
	V(wmutex);
}
解决方案:写者优先方案二
读者:
while(true)
{
	P(Z);
    P(S);
	P(mutex);//读者进入,申请修改读者数量
		readcount++;
		if(readcount==1)
			P(w);
	V(mutex);
	V(S);
	V(Z);
	读;
	P(mutex);//读者离开,,申请修改读者数量
		readcount--;
		if(readcount==0)
			V(w);
	V(mutex);
}
写者:
while(true)
{
	P(wmutex);//写者进入,申请修改写者数量
		writecount++;
		if(writecount==1)
			P(S);
	V(wmutex);
	P(w);V(w);
	P(wmutex);//写者离开,申请修改写者数量
		writecount--;
		if(writecount==0)
			V(S);
	V(wmutex);
}


int readcount;
semaphore x=1,wsem=1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值