`
中国爪哇程序员
  • 浏览: 167249 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

信号量与PV java

    博客分类:
  • java
 
阅读更多
进程间通信:
进程通常分为就绪、运行和阻塞三个工作状态。三种状态在某些条件下可以转换,三者之间的转换关系如下:

进程三个状态之间的转换就是靠PV操作来控制的。PV操作主要就是P操作、V操作和信号量。其中信号量起到了至关重要的作用。

信号量
信号量是最早出现的用来解决进程同步与互斥问题的机制。 
信号量(Saphore)由一个值和一个指针组成,指针指向等待该信号量的进程。信号量的值表示相应资源的使用情况。信号量S>=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个资源,因此S的值减1;当S<0时,表示已经没有可用资源,S的绝对值表示当前等待该资源的进程数。请求者必须等待其他进程释放该类资源,才能继续运行。而执行一个V操作意味着释放一个资源,因此S的值加1;若S<0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。

注意,信号量的值只能由PV操作来改变。
  
 
关于PV操作容易产生的一些疑问:

1,S大于0那就表示有临界资源可供使用,为什么不唤醒进程?
S大于0的确表示有临界资源可供使用,也就是说这个时候没有进程被阻塞在这个资源上,所以不需要唤醒。

2,S小于0应该是说没有临界资源可供使用,为什么还要唤醒进程?
V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使S加1,以通知其它的进程,这个时候如果S<0,表明有进程阻塞在该类资源上,因此要从阻塞队列里唤醒一个进程来“转手”该类资源。比如,有两个某类资源,四个进程A、B、C、D要用该类资源,最开始S=2,当A进入,S=1,当B进入S=0,表明该类资源刚好用完, 当C进入时S=-1,表明有一个进程被阻塞了,D进入,S=-2。当A用完该类资源时,进行V操作,S=-1,释放该类资源,因为S<0,表明有进程阻塞在该类资源上,于是唤醒一个。

3,如果是互斥信号量的话,应该设置信号量S=1,但是当有5个进程都访问的话,最后在该信号量的链表里会有4个在等待,也是说S=-4,那么第一个进程执行了V操作使S加1,释放了资源,下一个应该能够执行,但唤醒的这个进程在执行P操作时因S<0,也还是执行不了,这是怎么回事呢?
当一个进程阻塞了的时候,它已经执行过了P操作,并卡在临界区那个地方。当唤醒它时就立即进入它自己的临界区,并不需要执行P操作了,当执行完了临界区的程序后,就执行V操作。

4,S的绝对值表示等待的进程数,同时又表示临界资源,这到底是怎么回事?
当信号量S小于0时,其绝对值表示系统中因请求该类资源而被阻塞的进程数目.S大于0时表示可用的临界资源数。注意在不同情况下所表达的含义不一样。当等于0时,表示刚好用完。

某工厂有一个可以存放设备的仓库,总共可以存放10台设备。生产的每一台设备都必 须入库,销售部门可从仓库提出设备供应客户。设备的入库和出库都必须借助运输工具。现只有一台运输工具,每次只能运输一台设备。请设计一个能协调工作的自动调度管理系统。
参考答案:  第一步:确定进程  可以为入库(Pin)和出库(Pout)各设置一个进程 Pin进程:     生产了一台设备  使用运输工具入库 Pout进程:     使用运输工具出库

 提出设备供应客户  第二步:确定进程的同步、互斥关系   同步:当仓库中有空余位置存放设备时,设备才可以入库  同步:当仓库中有存放的设备时,设备才可以出库  互斥:运输工具是临界资源,要互斥访问  第三步:设置信号量   仓库中有空余位置数量,empty,初值10  仓库中有存放的设备数量,full,初值 0   为运输工具设置互斥信号量S,初值 1,表示当前可用  第四步:用伪代码描述 
begin      empty, full, S:semaphore;   
 empty := 10;  full := 0; S := 1; 
cobegin  Pin ();  
Pout (); coend; 
end;   
process  Pin ( )    begin        
L1:  生产了一台设备   P(empty);            
 P (S);  使用运输工具入库; 
V (S);             
V(full); 
goto L1;     
end;    
process  Pout ( )    begin  
L2:  P(full); 
 P (S);  使用运输工具出库; V (S); V(empty);  提出设备供应客户;             goto L2;     end; 


/**
 * 空余位置
 */
public class AvailablePositionSemaphore {

	private int num = 0;

	public AvailablePositionSemaphore(int num) {
		this.num = num;
	}

	public synchronized int p_AvailablePosition() throws InterruptedException {
		if (num >= 10) {
			wait();
		}
		return num--;
	}

	public synchronized int v_AvailablePosition() {
		this.notify();
		return num++;
	}
}


/**
 * 设备数量
 */
public class EquipmentSemaphore {

	private int num = 0;
	
	public EquipmentSemaphore(int num){
		this.num = num;
	}

	public synchronized int p_Equipment() {
		if (num > 0) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return num--;
	}

	public synchronized int v_Equipment() {
		this.notify();
		return num++;
	}
}


public class ToolSemaphore {

	private int num = 0;

	public ToolSemaphore(int num) {
		this.num = num;
	}

	public synchronized int p_Tool() {
		if (num <= 0) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return num--;
	}

	public synchronized int v_Tool() {
		this.notify();
		return num++;
	}
}


public class ProducerThread extends Thread {

	private AvailablePositionSemaphore availablePositionSemaphore;
	private EquipmentSemaphore equipmentSemaphore;
	private ToolSemaphore toolSemaphore;

	public ProducerThread(AvailablePositionSemaphore availablePositionSemaphore, EquipmentSemaphore equipmentSemaphore,
			ToolSemaphore toolSemaphore) {
		this.availablePositionSemaphore = availablePositionSemaphore;
		this.equipmentSemaphore = equipmentSemaphore;
		this.toolSemaphore = toolSemaphore;
	}

	public void buildNew() {
		System.out.println("buildNew begin");
		try {
			Thread.sleep(1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("buildNew end");
	}

	@Override
	public void run() {
		while (true) {
			try {
				buildNew();
				int num1 = availablePositionSemaphore.p_AvailablePosition();
				int num2 = toolSemaphore.p_Tool();
				toolSemaphore.v_Tool();
				equipmentSemaphore.v_Equipment();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}


public class ConsumerThread extends Thread {

	private AvailablePositionSemaphore availablePositionSemaphore;
	private EquipmentSemaphore equipmentSemaphore;
	private ToolSemaphore toolSemaphore;

	public ConsumerThread(AvailablePositionSemaphore availablePositionSemaphore, EquipmentSemaphore equipmentSemaphore,
			ToolSemaphore toolSemaphore) {
		this.availablePositionSemaphore = availablePositionSemaphore;
		this.equipmentSemaphore = equipmentSemaphore;
		this.toolSemaphore = toolSemaphore;
	}

	public void sell() {
		System.out.println("sell begin");
		try {
			Thread.sleep(1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("sell end");
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(2000L);
				int num1 = equipmentSemaphore.p_Equipment();
				int num2 = toolSemaphore.p_Tool();
				sell();
				toolSemaphore.v_Tool();
				availablePositionSemaphore.v_AvailablePosition();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}



	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AvailablePositionSemaphore a1 = new AvailablePositionSemaphore(10);
		EquipmentSemaphore a2 = new EquipmentSemaphore(0);
		ToolSemaphore a3 = new ToolSemaphore(1);
		ProducerThread producer = new ProducerThread(a1, a2, a3);
		ConsumerThread consumer = new ConsumerThread(a1, a2, a3);
		producer.start();
		consumer.start();
	}

分享到:
评论

相关推荐

    理发师问题-信号量PV操作实现

    理发师问题-信号量PV操作实现 本文探讨了理发师问题的解决方案,该问题是一个经典的多进程同步问题。通过使用信号量PV操作,实现了多线程同步,解决了理发师问题。下面是该解决方案的详细介绍。 信号量PV操作 ...

    java模拟实现PV操作

    在并发编程中,PV操作(即信号量Semaphore)是由荷兰计算机科学家Edsger Dijkstra提出的,它通过控制对共享资源的访问来避免竞态条件,确保线程间的同步。在Java中,我们可以使用内置的`java.util.concurrent`包中的...

    Java实现的进程同步与互斥(PV)

    其中,`Semaphore`类可以用来模拟信号量,从而实现PV操作。`Semaphore`维护了一个许可计数,当计数为0时,表示没有可用的资源,任何试图获取许可的线程将被阻塞,直到有其他线程释放许可。 P操作( acquire() )是...

    操作系统作业 (pv,作业管理,等5个的Java实现)

    首先,PV操作源于荷兰计算机科学家Edsger Dijkstra提出的信号量机制,它是并发控制的一种方法。P操作(Wait或 acquire)用于请求资源,V操作(Signal或 release)用于释放资源。在多线程环境下,PV操作可以防止数据...

    操作系统 PV操作 实验报告

    实验的目的不仅在于理解进程与程序的区别,深入认识并发执行的本质,还在于通过实际编程验证信号量机制在实现进程互斥和同步中的作用。在这个实验中,特别强调了避免死锁的概念,这是操作系统中非常重要的一环,银行...

    pv操作解析 了解pv操作

    它是“信号量”(Semaphore)的一个特例,由荷兰计算机科学家Edsger Dijkstra提出的“泛型信号量”(Generic Semaphore)机制中的两个基本操作。"P"代表"Proberen",在英文中意为"尝试"或"测试",而"V"代表"Verhogen...

    操作系统pv操作

    操作系统中的PV操作,源于荷兰计算机科学家埃德加·科德提出的信号量机制,是实现进程同步和...在实际开发中,Java的`java.util.concurrent`包提供了如`Semaphore`类,可以更直接地实现信号量机制,简化PV操作的实现。

    PV操作实验

    Java提供了`synchronized`关键字和`wait()`、`notify()`方法来实现线程同步,但为了模拟PV操作,可能需要自定义类来实现信号量的功能。在这个实验中,你需要理解如何在代码中使用这些同步原语,以及它们如何影响程序...

    android模拟PV操作

    在计算机科学领域,PV操作是进程同步的一种基本方法,由荷兰计算机科学家Edsger Dijkstra提出的信号量机制实现。在Android系统中,虽然它不是直接内建的功能,但可以通过编程来模拟实现。在这个操作系统课设中,我们...

    消费者与生产者pv源语

    消费者与生产者 pv源语 java形式表达 信号量

    PV操作示例代码

    在操作系统领域,PV操作是进程同步的基本工具,源自荷兰计算机科学家埃德加·科德(Edsger Dijkstra)提出的信号量(Semaphore)概念。PV操作由两个原子操作组成:P(Wait)操作和V(Signal)操作,主要用于解决多...

    C++ PV操作(生产者/消费者)简单实例

    PV 操作是信号量机制的基础组成部分,用来解决进程间的同步问题。其中,“P”操作(Wait 或 Down 操作)用来请求一个资源,“V”操作(Signal 或 Up 操作)用来释放一个资源。当生产者生产数据时,它会执行 V 操作来...

    FIFO.rar_FIFO Java

    本项目“FIFO.rar_FIFO Java”显然是一个用Java语言实现的版本,旨在通过模拟生产者和消费者来理解FIFO(先进先出)原则,并运用PV操作,即信号量(Semaphore)来解决资源的竞争问题。 1. **生产者与消费者问题**:...

    计算机操作系统理发师问题-JAVA.doc

    在 JAVA 中,我们可以使用 Semaphore 类来实现信号量。以下是使用 JAVA 实现理发师问题的示例代码: ```java package swxy; import java.util.concurrent.Semaphore; public class BarberShop { static int t = ...

    学号_姓名_操作系统_实验1_实验报告.docx

    使用 C 语言或 Java 语言实现生产者消费者进程同步算法,使用信号量和 PV 操作控制生产者和消费者的执行顺序。主文件名为 Synchronization。 8. 实验结论: 本实验共有 3 小题,已经完成了所有小题。在本次实验中,...

    Java操作系统课设之模拟进程管理系统

    在模拟中,可以使用这些工具来实现如管程、信号量、PV操作等经典同步原语。 4. **进程通信**:进程间通信(IPC)是操作系统中重要的组成部分。Java提供了多种通信方式,如管道(Pipes)、套接字(Sockets)、共享...

    操作系统实验进程调度报告.pdf

    在实验的过程中,我们使用Java语言编写程序,模拟三个进程的运行情况,进程在运行过程中要调用P操作申请信号量,如果该进程得到其申请的信号量,就继续运行,否则该进程被阻塞,并将进程置为所申请信号量的等待者,...

    操作系统pv操作.docx

    信号量是P、V操作的核心,它是一个整型变量,可以理解为资源的计数器。当信号量S大于或等于零时,表示资源可用;当S小于零时,意味着有负数个进程正在等待资源。P操作(减操作)会将信号量S减1,如果减后仍大于或...

    操作系统中哲学家就餐问题和生产者消费者问题实验报告

    在本次实验中,通过使用BACI并发程序设计系统,我们不仅深入理解了哲学家就餐问题和生产者消费者问题的实质,还掌握了如何利用信号量和PV操作来解决这些经典的并发编程问题。此外,实验还加深了我们对并发控制机制的...

    模拟PV操作同步机构

    Dijkstra提出的信号量机制。在这个机制中,"P"代表"Procedure"(或者"Pass"),表示等待资源;"V"代表"Value"(或者"Unlock"),表示释放资源。这种机制被广泛用于解决并发编程中的同步问题,特别是生产者-消费者...

Global site tag (gtag.js) - Google Analytics