【问题标题】:Am i using semaphore wrong?我使用信号量错了吗?
【发布时间】:2015-02-24 18:03:05
【问题描述】:

我需要使用信号量并行执行一些任务。我试试这个:

Semaphore sema = new Semaphore(2,2);
Thread[] Threads = new Thread[5];
for (int k = 0; k < 5; k++) {
    sema.WaitOne();
    Console.WriteLine((k + 1) + " started");
    Threads[k] = new Thread(ThreadMethod1);
    Threads[k].Start(k + 1);
    sema.Release();
}

static void ThreadMethod1(object id) {
    Thread.Sleep(50);
    Console.WriteLine(id + " completed");
}

输出如下:

1 started
2 started
3 started
4 started
5 started
1 completed
2 completed
4 completed
3 completed
5 completed

信号量不应该只让 2 个线程运行吗?我不明白还是做错了什么?

【问题讨论】:

  • 是的,但是你是在每个循环的主线程中进入退出信号量,所以信号量会一直处于非阻塞状态。

标签: c# multithreading semaphore


【解决方案1】:

您正在“主”线程中输入/退出信号量。这是没用的,因为在每个“循环”中你都会进入和退出它。在这个修改后的示例中,您在主线程中输入信号量,并在完成工作线程后退出它。

请注意,我必须将信号量传递给工作线程(我使用了Tuple,但其他方法都可以)

static void Main(string[] args) {
    Semaphore sema = new Semaphore(2, 2);

    Thread[] Threads = new Thread[5];
    for (int k = 0; k < 5; k++) {
        sema.WaitOne();

        Console.WriteLine((k + 1) + " started");

        Threads[k] = new Thread(ThreadMethod1);
        Threads[k].Start(Tuple.Create(k + 1, sema));
    }
}

static void ThreadMethod1(object tuple) {
    Tuple<int, Semaphore> tuple2 = (Tuple<int, Semaphore>)tuple;
    Thread.Sleep(50);
    Console.WriteLine(tuple2.Item1 + " completed");
    tuple2.Item2.Release();
}

您可以将sema.WaitOne 移动到ThreadMethod1 的“内部”,但这会有所不同:所有线程都将被创建但会“等待”,并且一次只有2 个线程会执行“实际工作”。正如所写的那样,最多创建两个线程(并完成工作)

【讨论】:

  • 看起来我很累,无法正常思考。谢谢!
【解决方案2】:

您所要做的就是将信号量上的操作从主线程中移出。对您的代码稍作修正即可解决问题。

public static Semaphore sema = new Semaphore(2, 2);

static void Main(string[] args)
{
    Thread[] Threads = new Thread[5];
    for (int k = 0; k < 5; k++)
    {
        Console.WriteLine((k + 1) + " started");
        Threads[k] = new Thread(ThreadMethod1);
        Threads[k].Start(k + 1);
    }
}

static void ThreadMethod1(object id)
{
    sema.WaitOne();
    Thread.Sleep(1000);
    Console.WriteLine(id + " completed");
    sema.Release();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多