C# 这个代码会导致死锁吗? 使用系统; 使用系统线程; 命名空间线程 { 班级计划 { 静态void Main(字符串[]参数) { 信号量偶数=新信号量(1,1); 信号量奇数=新信号量(1,1); 线程事件线程=新线程(()=> { 对于(int i=1;i { 对于(int i=1;i

C# 这个代码会导致死锁吗? 使用系统; 使用系统线程; 命名空间线程 { 班级计划 { 静态void Main(字符串[]参数) { 信号量偶数=新信号量(1,1); 信号量奇数=新信号量(1,1); 线程事件线程=新线程(()=> { 对于(int i=1;i { 对于(int i=1;i,c#,deadlock,C#,Deadlock,要发生死锁,两个或多个线程必须尝试获取两个或多个资源,但顺序不同。请参阅和 您的代码不涉及每个线程†一个以上的锁,因此不具备死锁功能 它确实能够引发异常。如中所述,理论上,其中一个线程可能远远领先于另一个线程,从而尝试释放尚未执行的信号量锁。例如,如果evenThread被抢占(或者根本没有计划开始运行)在它第一次调用偶数.WaitOne(),但oddThread运行之前,oddThread可以获取odd信号量,处理if语句,然后在evenThread有机会获取该信号量之前尝试调用偶数.Rele

要发生死锁,两个或多个线程必须尝试获取两个或多个资源,但顺序不同。请参阅和

您的代码不涉及每个线程†一个以上的锁,因此不具备死锁功能

它确实能够引发异常。如中所述,理论上,其中一个线程可能远远领先于另一个线程,从而尝试释放尚未执行的信号量锁。例如,如果
evenThread
被抢占(或者根本没有计划开始运行)在它第一次调用
偶数.WaitOne()
,但
oddThread
运行之前,
oddThread
可以获取
odd
信号量,处理
if
语句,然后在
evenThread
有机会获取该信号量之前尝试调用
偶数.Release()

这将导致调用
Release()
引发
信号量lexception

在单CPU系统上,这种可能性更大,这在现在很难找到。:)但在理论上,任何CPU配置都是可能的



†实际上,
Console.WriteLine()中有一个隐式锁
call,这在设计上是线程安全的。但从代码的角度来看,这是一个原子操作。代码不可能获取该锁然后等待另一个锁。因此它与您的特定问题没有任何关系。

错误初始化信号量将很容易做到这一点。请注意,您的操作是错误的,您可能会出错创建了一个竞争条件,两个线程将同时尝试WriteLine()。理想情况下,它将崩溃,因为您对一个未等待但不会经常发生的信号量调用Release。但不,没有死锁。System.Threading.Barrier类可以做到这一点,当您不必重新发明它时,它会更好。
using System;
using System.Threading;

namespace Threading
{
class Program
{
    static void Main(string[] args)
    {
        Semaphore even = new Semaphore(1, 1);
        Semaphore odd = new Semaphore(1, 1);

        Thread evenThread = new Thread(() =>
        {
            for (int i = 1; i <= 100; i++)
            {
                even.WaitOne();
                if(i % 2 == 0)
                {
                    Console.WriteLine(i);
                }
                odd.Release();
            }
        });

        Thread oddThread = new Thread(() => 
        {
            for(int i = 1; i <=100; i++)
            {
                odd.WaitOne();
                if(i%2 != 0)
                {
                    Console.WriteLine(i);
                }
                even.Release();
            }
        });


        oddThread.Start();
        evenThread.Start();
    }


}
}