c# - 为什么在使用信号量时这 4 个线程会被锁定?
问题描述
在一个可能有很多很多线程的系统中,我试图确保一次只实例化一个类的四个实例,并且可能在 5-60 秒后释放。实例在每个线程开始时创建,并在线程中的进程结束时销毁。
我还想防止一次只构建一个实例。所以我的逻辑是在对象实例化期间使用锁,但也用信号量包装整个线程逻辑。
private static readonly object padlock = new object();
private static readonly Semaphore mutablelock = new Semaphore(0, 4);
// called at the start of a long running thread
public static Object GetNewInstance()
{
// semaphore used to prevent more than 4 objects from existing at any time
mutablelock.WaitOne();
// lock used to prevent more than one object being instantiated at a time
lock (padlock)
{
var instance = new Object();
return instance;
}
}
// called at the end of a long running thread
public static void ReleaseInstance()
{
mutablelock.Release();
}
该程序有四个线程(当使用调试停止点查看时)每个线程都停止在该mutablelock.WaitOne();
行并且不再继续前进。
解决方案
您正在构建您Semaphore
的所有条目都已保留的方式。Semaphore
接受两个参数的构造函数有这样的说法:
如果initialCount小于maximumCount,则效果与当前线程已调用
WaitOne
(maximumCount减去initialCount)次相同。如果您不想为创建信号量的线程保留任何条目,请对maximumCount和initialCount使用相同的数字。
所以做这个改变:
private static readonly Semaphore mutablelock = new Semaphore(4, 4);
推荐阅读
- ansible - Ansible 更新 yum 人性化输出
- c# - 比较坐标时无法从 int 转换为 System.Drawing.Point
- java - Swing 分层 - 透明组件忽略底层 AWT 元素
- php - PHP中POST Sanitation和Prepared语句之间的区别
- scala - Scala Left Join 返回 Full Join 的结果
- angular - forkJoin 上的 takeUntil 是否会调用 forkJoined observables 上的函数?
- vuepress - 只有我通过纱线尝试时,Vuepress 开发服务器无法正常工作
- javascript - 如何使用 Jquery 获取添加的输入字段的值?
- python - 如何从 Python 发送 AMP 电子邮件?它在技术上与普通电子邮件有何不同
- ios - 将 httpBody 转换为 x-www-urlencoded