C# 多线程:计算器池
C# MultiThreading: pool of calculators
我想要一个静态(全局)计算器池,它将被许多不同的线程访问。
经过一些研究,我发现数组的元素是线程安全的。
我认为将不同的计算器(直到运行时数量未知)存储在静态数组(计算器[]计算器)中是个好主意。
如何确保一台计算器只使用一台计算器?
我阅读了整个 msdn 文档,所以请不要 post "only" 链接。
我也考虑过布尔数组"locked"但是我找不到实现这个线程安全的方法。
到目前为止我的代码:
internal static class Calculators
{
private static Semaphore pool;
private static bool[] locked;
private static calcs[] neuralNetworks;
private static Thread[] threads;
internal static Calculators(){
int number = Globals.Number;
pool = new Semaphore(number, number);
locked = new bool[number];
calcs = new calcs[number];
threads = new Thread[number];
for (int index = 0; index < number; index++)
{
// all neuralNetworks are unlocked by default
locked[index] = false;
// generate one network per "countThreads"
calcs[index] = Globals.CalcObj;
// generate one thread for each neural network
threads[index] = new Thread(new ThreadStart());
}
}
private int WhichCalculators()
{
int index;
for (index = 0; index < countThreads; index++)
{
if (locked[index] == false)
{
locked[index] = true;
return index;
}
}
throw new Exception("Calculators was called, but there weren't any networks unused");
}
}
代码更新:
如果我在这个方法中调用 "WhichCalculator()" 那么它应该工作吗?
private static void doStuff()
{
pool.WaitOne();
Monitor.Enter(thisLock);
try
{
int whichCalculator = WhichCalculator();
locked[whichCalculator] = true;
lock (calculators[whichCalculator])
{
Monitor.Exit(thisLock);
// do stuff
locked[whichCalculator] = false;
}
}
catch
{
Monitor.Exit(thisLock);
}
//Calculate();
pool.Release();
}
问题 2:
我是否正确地假设,静态构造函数将在第一次(但之前)此 class 或其任何成员将被访问时立即执行?
您可以 lock 您的阵列。这将确保每个数组操作都是线程安全的。
为确保每个对象一次仅使用一次,您可以为其添加一个标志,如 calculator.InUse
。如果无法向 class 添加标志,则可以使用 extension method.
是的,你必须使用锁。但是又是数组和计算器的每个实例。
如果您可以在开始代码的多线程部分之前填充数组,则您也不需要锁定数组(由于静态内容,仅读取不会造成问题)但是调整数组大小需要锁定对其的每次访问(写入和读取)。
所以您的代码可能如下所示:
Calculator calc = null;
lock(calculators)
{
calc = calculators[0];
}
lock(calc)
{
// ... do stuff
}
这样数组就不再需要锁定了,您可以锁定计算器本身。
我想要一个静态(全局)计算器池,它将被许多不同的线程访问。 经过一些研究,我发现数组的元素是线程安全的。 我认为将不同的计算器(直到运行时数量未知)存储在静态数组(计算器[]计算器)中是个好主意。
如何确保一台计算器只使用一台计算器?
我阅读了整个 msdn 文档,所以请不要 post "only" 链接。
我也考虑过布尔数组"locked"但是我找不到实现这个线程安全的方法。
到目前为止我的代码:
internal static class Calculators
{
private static Semaphore pool;
private static bool[] locked;
private static calcs[] neuralNetworks;
private static Thread[] threads;
internal static Calculators(){
int number = Globals.Number;
pool = new Semaphore(number, number);
locked = new bool[number];
calcs = new calcs[number];
threads = new Thread[number];
for (int index = 0; index < number; index++)
{
// all neuralNetworks are unlocked by default
locked[index] = false;
// generate one network per "countThreads"
calcs[index] = Globals.CalcObj;
// generate one thread for each neural network
threads[index] = new Thread(new ThreadStart());
}
}
private int WhichCalculators()
{
int index;
for (index = 0; index < countThreads; index++)
{
if (locked[index] == false)
{
locked[index] = true;
return index;
}
}
throw new Exception("Calculators was called, but there weren't any networks unused");
}
}
代码更新: 如果我在这个方法中调用 "WhichCalculator()" 那么它应该工作吗?
private static void doStuff()
{
pool.WaitOne();
Monitor.Enter(thisLock);
try
{
int whichCalculator = WhichCalculator();
locked[whichCalculator] = true;
lock (calculators[whichCalculator])
{
Monitor.Exit(thisLock);
// do stuff
locked[whichCalculator] = false;
}
}
catch
{
Monitor.Exit(thisLock);
}
//Calculate();
pool.Release();
}
问题 2: 我是否正确地假设,静态构造函数将在第一次(但之前)此 class 或其任何成员将被访问时立即执行?
您可以 lock 您的阵列。这将确保每个数组操作都是线程安全的。
为确保每个对象一次仅使用一次,您可以为其添加一个标志,如 calculator.InUse
。如果无法向 class 添加标志,则可以使用 extension method.
是的,你必须使用锁。但是又是数组和计算器的每个实例。
如果您可以在开始代码的多线程部分之前填充数组,则您也不需要锁定数组(由于静态内容,仅读取不会造成问题)但是调整数组大小需要锁定对其的每次访问(写入和读取)。 所以您的代码可能如下所示:
Calculator calc = null;
lock(calculators)
{
calc = calculators[0];
}
lock(calc)
{
// ... do stuff
}
这样数组就不再需要锁定了,您可以锁定计算器本身。