我使用信号量错了吗?

Inf*_*eus 1 c# multithreading semaphore

我需要使用信号量并行完成一些任务.我试试这个:

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");
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

1 started
2 started
3 started
4 started
5 started
1 completed
2 completed
4 completed
3 completed
5 completed
Run Code Online (Sandbox Code Playgroud)

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

xan*_*tos 8

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

请注意,我必须将信号量传递给工作线程(我使用了a 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();
}
Run Code Online (Sandbox Code Playgroud)

你可以移动sema.WaitOne"内部" ThreadMethod1,但它会有所不同:所有的线程都会被创建,但是会"等待",一次只能做2次"真正的工作".正如所写,最多创建两个线程(并完成工作)