Semaphore详解2

在前面我们已经介绍了acquire(int permits) 的功能是每调用1次此方法,就调用参数大小的许可,我们可以通过多次调用release()方法可以动态的增加许可的个数

availablePermits方法返回Semaphore对象中当前可用的许可数

drainPermits方法获取并返回可用的许可数,并将许可数设置为0

步骤:

1,创建一个工程,我的工程目录如下图


2,创建一个类,(我这里的类名是TestSemaphore)这个类用于实例化Semaphore类,并确定线程需要执行的代码。

package cn.wxz.test;
import java.util.concurrent.Semaphore;
public class TestSemaphore {
	Semaphore semaphore= new Semaphore(10);
	public void  test(){
		try {
			semaphore.acquire();
	System.out.println(semaphore.availablePermits());
			semaphore.release();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
测试类Test代码如下:

package cn.wxz.test;
public class Test {
	public static void main(String[] args) {
		TestSemaphore testSemaphore = new TestSemaphore();
	testSemaphore.test();
	}
}
运行结果,如图



分析如下,因为new Semaphore(10);运行10个许可,acquire();默认使用了一个,即还剩下9个

接下来我们验证release()接下来我们验证方法可以动态添加许可数,只需要把TestSemaphore类修改如下

package cn.wxz.test;
import java.util.concurrent.Semaphore;
public class TestSemaphore {
	Semaphore semaphore= new Semaphore(10);
	public void  test(){
		try {
			semaphore.acquire();
	System.out.println(semaphore.availablePermits());
			semaphore.release();
			semaphore.release();
			semaphore.release();
			semaphore.release();
			semaphore.release();
			System.out.println(semaphore.availablePermits());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
test类代码不变,运行结果如下


因为我们增加了5个semaphore.release();即动态添加了5个许可数,加上以前的9个即最终变为14了

最后验证drainPermits方法
把TestSemaphore类修改如下

package cn.wxz.test;
import java.util.concurrent.Semaphore;
public class TestSemaphore {
	Semaphore semaphore= new Semaphore(10);
	public void  test(){
		try {
			semaphore.acquire();
	System.out.println(semaphore.availablePermits());
	System.err.println(semaphore.drainPermits());
			semaphore.release();
			semaphore.release();
			semaphore.release();
			semaphore.release();
			semaphore.release();
			System.out.println(semaphore.availablePermits());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

运行结果如下



因为调用了drainPermits方法,立即返回当前的可用的许可数即第二个为9,并将许可数设置为0,因调用了drainPermits后又调用了5次release方法即动态增加了5个许可数即第三个数值是5

### Python `multiprocessing` 中 `Semaphore` 的使用详解 #### 什么是 `Semaphore` `Semaphore` 是一种同步原语,用于控制对共享资源的并发访问。它可以限制同时进入某个临界区的线程或进程量。通过初始化时指定的一个计值,`Semaphore` 可以允许多个进程/线程竞争同一资源[^1]。 当一个进程调用 `acquire()` 方法时,如果当前可用的信号量大于零,则该进程会获得信号量并将其减一;否则,该进程会被阻塞直到有其他进程释放信号量(即调用 `release()` 方法)[^2]。 #### 原理分析 - **初始值设置**:在创建 `Semaphore` 对象时可以通过参设定其最大允许同时运行的任务。 - **获取资源 (`acquire`) 和释放资源 (`release`)**: - 调用 `acquire()` 表示请求占用一个单位的资源。 - 如果此时剩余可分配资源不足,则调用方将被挂起等待。 - 当不再需要此资源时应显式地调用 `release()` 来归还所占有的资源单元给系统以便后续任务能够继续执行下去[^3]。 #### 示例代码展示 以下是基于官方文档以及实际应用场景构建的一段演示如何利用 `multiprocessing.Semaphore` 实现多进程之间协调工作的例子: ```python from multiprocessing import Semaphore, Process import time def task(name, sem): """模拟耗时操作""" print(f"{name}: 尝试获取信号量...") # 请求获取信号量 sem.acquire() try: print(f"{name}: 成功获取到信号量.") # 模拟业务逻辑处理过程 time.sleep(2) print(f"{name}: 完成工作.") finally: # 不管发生什么情况都要记得释放信号量 sem.release() if __name__ == "__main__": # 创建一个只允许两个进程同时进入的关键区域 semaphore = Semaphore(2) jobs = [] for i in range(5): job = Process(target=task, args=(f"Worker-{i}", semaphore)) jobs.append(job) job.start() for j in jobs: j.join() ``` 在这个脚本里我们定义了一个名为 `task` 的函代表每一个独立的工作项,在这个过程中它们都需要先尝试取得由变量 `semaphore` 所表示的那个互斥锁才能正式开始自己的主要活动——这里为了简化描述就让每个工作者睡两秒钟作为他们各自要做的具体事情。注意每次循环都会新启一个新的子进程来负责不同的实例化后的作业对象,并且最后还要确保主线程等到所有的这些分支都结束了才退出整个应用程序。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值