AND信号

互斥的上述处理,它是针对仅在进程之间共享的一个关键资源方面。在一些应用。这是一个过程,需要在为了自己的使命后,获得两个或多个其他共享资源运行。

个进程A和B。他们都要求訪问共享数据D和E。

当然,共享数据都应作为临界资源。为此。可为这两个数据分别设置用于相互排斥的信号量Dmutex和Emutex,并令它们的初值都是1;

AND同步机制的基本思想是:将进程在整个执行过程中须要的所有资源,一次性所有地分配给进程,待进程使用完后再一起释放。仅仅要尚有一个资源未能分配给进程。其他所有可能为之分配的资源也不分配给它。亦即,对若干个临界资源的分配,採取原子操作方式:要么把它所请求的资源所有分配到进程,要么一个也不分配。

由死锁理论可知,这样就可避免上述死锁情况的发生。为此。在wait操作中。添加了一个“AND”条件,故称为AND同步,或称为同一时候wait操作。

伪代码:例如以下:

Swait(S1。S2,…。Sn)

  if Si>=1 and … and Sn>=1 then

   for i:=1 to n do

   Si:=Si-1。

   endfor

  else

  place the process in the waiting queue associated with the first Si found with Si<1,and set the program count of this process to the beginning of Swait operation

  endif

Ssignal(S1,S2。…,Sn)

for i:=1 to n do

  Si:=Si+1。

Remove all the process waiting in the queue associated with Si into the ready queue.

endfor。

Java代码:

package org.hao.andpv;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

public class AndPV {

private int[] semaphores;//信号量数组

private List<BlockingQueue<Thread>> queueList=new ArrayList<BlockingQueue<Thread>>();

//每一个信号量相应的堵塞队列

public AndPV(int[] semaphores) {//设置信号量初值,初始化

this.semaphores=semaphores;

for(int i=0;i<semaphores.length;i++){

queueList.add(new LinkedBlockingQueue<Thread>());

}

}

public synchronized void p(Thread t) {//p原语

int semaphoreIndex=0;

for(;semaphoreIndex<semaphores.length;semaphoreIndex++){//推断每一个条件是否都满足

if(semaphores[semaphoreIndex]<1){//第semaphoreIndex个条件不满足

break;

}

}

if(semaphoreIndex<semaphores.length-1){//条件不满足时

queueList.get(semaphoreIndex).add(t);//加入到堵塞队列

try {

synchronized(t){

t.wait();//线程堵塞

}

} catch (Exception e) {

}

}else{

for(semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

semaphores[semaphoreIndex]--;//条件满足时。可用资源都减一

}

}

}

public synchronized void v(){ //v原语

for(int semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

semaphores[semaphoreIndex]++;//进程执行完,可用资源都增一

if(semaphores[semaphoreIndex]>=0){//第semaphoreIndex类有可用资源

Thread t=queueList.get(semaphoreIndex).poll();

synchronized(t){

t.notify();

p(t);//推断其它条件是否满足

}

}

}

}

}

信号量集

  在记录型信号量机制中。wait(S)或signal(S)操作仅能对信号量施以加1或减1操作。意味着每次仅仅能获得或释放一个单位的临界资源。而当一次须要N个某类临界资源时,便要进行N次wait(S)操作。显然这是低效的。此外。在有些情况下。当资源数量低于某一下限值时,便不予以分配。

因而,在每次分配之前,都必须測试该资源的数量,看其是否大于其下限值。基于上述两点,能够对AND信号量机制加以扩充。形成一般化的“信号量集”机制。Swait操作可描写叙述例如以下,当中S为信号量,d为需求值,而t为下限值。

package org.hao.andpv;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

public class CollectPV {

private int[] semaphores;

private List<BlockingQueue<Thread>> queueList=new ArrayList<BlockingQueue<Thread>>();

private Map<Thread,Integer[]> map=new HashMap<Thread,Integer[]>();//保存第线程的请求

public CollectPV(int[] semaphores) {

this.semaphores=semaphores;

for(int i=0;i<semaphores.length;i++){

queueList.add(new LinkedBlockingQueue<Thread>());

}

}

public synchronized void p(Thread t,Integer[] semas) {

try {

int semaphoreIndex=0;

for(;semaphoreIndex<semaphores.length;semaphoreIndex++){

if(semaphores[semaphoreIndex]<semas[semaphoreIndex]){

break;

}

}

if(semaphoreIndex<semaphores.length){

BlockingQueue<Thread> blockingQueue=queueList.get(semaphoreIndex);

blockingQueue.add(t);

queueList.add(semaphoreIndex, blockingQueue);

map.put(t, semas);

try {

synchronized(t){

t.wait();

}

} catch (Exception e) {

}

}else{

for(int semaphoresIndex=0;semaphoresIndex<semaphores.length;semaphoresIndex++){

semaphores[semaphoresIndex]-=semas[semaphoresIndex];

}

}

} catch (Exception e) {

}

}

public synchronized void v(Integer[] semas){

try {

for(int semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

semaphores[semaphoreIndex]+=semas[semaphoreIndex];

if(semaphores[semaphoreIndex]>=0){

Thread t=queueList.get(semaphoreIndex).poll();

synchronized(t){

t.notify();

p(t, map.get(t));

}

}

}

} catch (Exception e) {

}

}

}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

AND信号灯和信号灯集-----同步和互斥解决面向对象(两)的更多相关文章

  1. ipcclean - 从退出的PostgreSQL服务器中删除共享内存和信号灯

    SYNOPSIS ipcclean DESCRIPTION 描述 ipcclean 删除当前用户拥有的所有共享内存段和信号灯集. 它的目地是在 PostgreSQL 服务器 (postmaster(1 ...

  2. 【Linux多线程】同步与互斥的区别

    同步与互斥这两个概念经常被混淆,所以在这里说一下它们的区别. 一.同步与互斥的区别 1. 同步 同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行. ...

  3. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  4. exec函数族,守护进程,线程同步和互斥

    2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...

  5. Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...

  6. C++ 11 线程的同步与互斥

    这次写的线程的同步与互斥,不依赖于任何系统,完全使用了C++11标准的新特性来写的,就连线程函数都用了C++11标准的lambda表达式. /* * thread_test.cpp * * Copyr ...

  7. JAVA 多线程同步与互斥

    1. 为什么需要互斥: ​互斥操作  保证了  多线程操作的  原子性 , java的 互斥 语义 有 synchronized 关键字 提供. 主要方式 有  同步代码块 和  同步方法 两种 2. ...

  8. Windows下C++多线程同步与互斥简单运用

    1.  互斥量,Mutex #include <Windows.h> #include <iostream> using namespace std; DWORD WINAPI ...

  9. UNIX环境高级编程——线程同步之互斥量

    互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...

随机推荐

  1. poj 动态规划的主题列表和总结

    此文转载别人,希望自己可以做完这些题目. 1.POJ动态规划题目列表 easy:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, ...

  2. python语言学习3 ——第一个python程序

    输入exit即退出,这样写的缺点是没有保存已经写的代码,下次需要重新写

  3. hdu1260(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1260 分析:简单dp,dp[i]=min(dp[i-1]+a[i],dp[i-2]); #includ ...

  4. uboot启动阶段修改启动参数方法及分析

    作者:围补 本来启动方式这节不是什么复杂的事儿,不过想简单的说清楚明白,还真是不知道怎么组织.毕竟文字跟有声语言表达有别.但愿简单的东西别让我讲的太复杂! Arm板系统文件一般有三个——bootloa ...

  5. deinstall oracle 11g on linux

    deinstall oracle 11g on linux   From 11gR2, oracle provide us an deinstall tool. With that now we ca ...

  6. 数据库关于group by 两个或以上条件的分析

    首先group by 的简单说明:    group by 一般和聚合函数一起使用才有意义,比如 count sum avg等,使用group by的两个要素:    (1) 出现在select后面的 ...

  7. 设计模式六大原则(4):接口隔离原则(Interface Segregation Principle)

    接口隔离原则: 使用多个专门的接口比使用单一的总接口要好. 一个类对另外一个类的依赖性应当是建立在最小的接口上的. 一个接口代表一个角色,不应当将不同的角色都交给一个接口.没有关系的接口合并在一起,形 ...

  8. 使用dom4j创建和解析xml

    之前工作中用到了,相信写java的都会碰到xml,这里写了两个方法,创建和解析xml,废话不多说,直接上代码 package xml; import java.io.File; import java ...

  9. 完全合并C++面试题

    C++面试题 1.是不是父母写了virtual 功能,假设子类重写它的功能不virtual ,也使多态性? virtual修饰符隐形遗传. private 还集成.问权限而已 virtual可加可不加 ...

  10. MFC漆摘要-截图,获得DIB/DDB图形Pixel

    1.       当前Screen进行Copy屏幕,获得BITMAP 当前屏幕Copy.须要获取当前屏幕的HDC, 一种是直接从屏幕DC抓原始图. 一种是然后使用兼容MemDC进行抓图,然后能够附加图 ...