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. 【iOS】苹果,百度Map定位使用与总结

    iOS中使用较多的3款地图,google地图.百度地图.苹果自带地图(高德).当中苹果自带地图在中国使用的是高德的数据.苹果在iOS 6之后放弃了使用谷歌地图,而改用自家的地图.在国内使用的较多的就是 ...

  2. Filezilla出现中文乱码

    使用Filezilla client FTP客户端登陆某些FTP站点会出现中文乱码,原因是FTP服务器端编码与filezilla client端编码不一致造成的,解决方法如下:文件-站点管理-选中要登 ...

  3. A Game of Thrones(15) - Sansa

    Eddard Stark had left before dawn, Septa Mordane informed Sansa as they broke their fast. “The king ...

  4. POJ2155:Matrix(二维树状数组,经典)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  5. String的split

    对于  http://10.13.30.22/svn/SVNRepository/UnChecked/Test  想要分割他就要用: String subContent[]=modelInfo.get ...

  6. 异常学习笔记+打包+doc该软件包编译

    jvm调用默认的异常处理机制printStackTrace办法      欲了解更多异常处理.问题      捕获异常代码块出现继承关系 应该把被继承的异常放在子类异常块的后面 watermark/2 ...

  7. HDU 4380 Farmer Greedy 计算几何+bitset

    枚举直线,对于直线的某个点在直线的左端还是右端,能够状压出一个数.用bitset记录. 然后三角形就是3个bitset&一下 #include <cstdio> #include ...

  8. zabbix 监控特定进程

    因为一些server上跑着一些重要程序,须要对它们进行监控,公司用的是zabbix监控,之前都是在zabbix中加入自己定义脚本对特定程序进行监控,近期看了zabbix的官方文档,发现原来强大的zab ...

  9. sql语句用'in'执行多条语句时候,执行错误的解决方法

    一般报错是出现,无法将nvarchar类型转换为int类型 这是因为 SqlParameter  带参数  是不能用  , 分割的. 第一种解决方法就是  不用 SqlParameter  带参数的s ...

  10. DLNA它 Error, can&#39;t findlibavformat ! 解

    DLNA库版本号为libdlna-0.2.4 运行./configure出错: ------------------------------ Error, can't findlibavformat ...