我该如何“等待不止一个人”?在信号量中

本文关键字:信号量 一个人 不止 等待 | 更新日期: 2023-09-27 18:05:22

是否有办法在一个信号量中等待多个Release() ?

假设我有这样的东西:

class GoRunners {
    Semaphore runnersSemaphore;
    List<Result> results = new List<Result>();
    private void RunForestRun(object aRunner) {
        runnersSemaphore.Wait();
        Runner runner = (Runner)aRunner;
        results.Add(runner.Run());
        runnersSemaphore.Release();
    }
    private List<Result> Go() {
        List<Runners>() runners = CreateSomeRunners();
        runnersSemaphore = new Semaphore(2, 2); // At most two threads at once
        runners.ForEach((runner) => new Thread(RunForestRun).Start(runner); )}
        runnersSemaphore.WaitFor(runners.Count); //How do I do this?
        return results;
    }
}

我知道我可以在循环中使用多个WaitOne(),但这看起来不太好。但如果没有别的办法,我也无所谓。如果有另一种机制可以实现我想要的,那也没关系(我曾经在Java中使用信号量做过类似的事情,所以我的想法是朝着那个方向发展的)。

注意:我被锁在。net 3.5:(

我该如何“等待不止一个人”?在信号量中

您需要将速率限制代码移动到foreach循环中,这样循环在所有运行程序启动之前不会退出。一旦你完成了,你只需要等待剩下的两个跑步者完成,在你返回结果之前。

class GoRunners {
    Semaphore runnersSemaphore;
    List<Result> results = new List<Result>();
    private void RunForestRun(object aRunner) {
        try {
            Runner runner = (Runner)aRunner;
            var result = runner.Run(); 
            lock(results)
            {
                results.Add(result)//List is not thread safe, you need to lock on it or use a different threadsafe collection (I don't know if there are any in .NET 3.5)
            }
        }
        finally { //A little safety in case a execption gets thrown inside "runner.Run()"
            runnersSemaphore.Release();
        }
    }
    const int MAX_RUNNERS = 2; //I hate magic numbers in code if they get spread across more than one line, move the max out to a const variable.
    private List<Result> Go() {
        List<Runners>() runners = CreateSomeRunners();
        runnersSemaphore = new Semaphore(MAX_RUNNERS, MAX_RUNNERS); // At most two threads at once
        foreach(var runner in runners)
        {
            runnersSemaphore.WaitOne(); //This goes in here now. New threads will not be started unless there is less than 2 runners running.
            new Thread(RunForestRun).Start(runner);
        }
        for(int i = 0; i < MAX_RUNNERS; i++) {
            runnersSemaphore.WaitOne(); //Wait for the currently running runners to finish.
        }
        return results;
    }
}