C#MultiThreading:计算器池

时间:2015-07-09 14:10:54

标签: c# arrays multithreading thread-safety pool

我希望有一个静态(全局)计算器池,这些计算器将由许多不同的线程访问。 经过一番研究后,我发现Arrays的元素是线程安全的。 我认为将不同的计算器(在运行时之前的数量未知)存储在静态数组(calculator []计算器)中是个好主意。

如何确保一个计算器只使用一个计算器? 我阅读了整个msdn文档,所以不要发布"只有"请链接。

我还考虑过一个bool阵列"锁定"但我无法找到实现此线程安全的方法。

到目前为止我的代码:

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");
}

}

代码更新: 如果我打电话给#34; WhichCalculator()&#34;那么它应该工作吗?在这个方法?

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: 我是否正确地假设,静态构造函数将在第一次(或之前)第一次执行此类或其任何成员时执行?

2 个答案:

答案 0 :(得分:1)

是的,你必须使用锁。但是数组和计算器的每个实例都会再次出现。

如果你可以在启动代码的多线程部分之前填充数组,那么你也不需要锁定数组(只有读取不会因静态内容而产生问题),但是通过调整数组大小,你需要锁定每个数组。访问它(写作和阅读)。 所以你的代码看起来像这样:

Calculator calc = null;
lock(calculators)
{
    calc = calculators[0];

}
lock(calc)
{
    // ... do stuff
}

这样,数组不再被锁定,然后需要锁定计算器本身。

答案 1 :(得分:0)

你可以lock你的阵列。这将确保每个数组操作都是线程安全的。

要确保每个对象一次只使用一次,您可以向其添加标记,例如calculator.InUse。如果您无法在课程中添加标记,则可以使用extension method