我使用信号量错了吗?
Am i using semaphore wrong?
我需要使用信号量并行执行一些任务。我试试这个:
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
semaphore 不是应该只让 2 个线程到 运行 吗?我不明白或做错了什么?
您是 entering/exiting 线程中的信号量。它没用,因为在每个 "cycle" 中你都会进入和退出它。在这个修改后的示例中,您在主线程中输入信号量,并在完成工作线程后退出它。
请注意,我必须将信号量传递给工作线程(我使用了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
"inside" 移动到 ThreadMethod1
,但它会有所不同:将创建所有线程,但会 "wait" 并且一次只能创建 2 个线程时间会做 "real work"。正如所写的那样,最多创建两个线程(并完成工作)
您所要做的就是将信号量上的操作从主线程中移出。对您的代码稍作更正即可解决问题。
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();
}
我需要使用信号量并行执行一些任务。我试试这个:
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
semaphore 不是应该只让 2 个线程到 运行 吗?我不明白或做错了什么?
您是 entering/exiting 线程中的信号量。它没用,因为在每个 "cycle" 中你都会进入和退出它。在这个修改后的示例中,您在主线程中输入信号量,并在完成工作线程后退出它。
请注意,我必须将信号量传递给工作线程(我使用了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
"inside" 移动到 ThreadMethod1
,但它会有所不同:将创建所有线程,但会 "wait" 并且一次只能创建 2 个线程时间会做 "real work"。正如所写的那样,最多创建两个线程(并完成工作)
您所要做的就是将信号量上的操作从主线程中移出。对您的代码稍作更正即可解决问题。
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();
}