Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 信号量同步_C#_Multithreading_Synchronization - Fatal编程技术网

C# 信号量同步

C# 信号量同步,c#,multithreading,synchronization,C#,Multithreading,Synchronization,我尝试使用Semaphoreclass同步三个线程(名为“1”、“2”和“3”)。他们必须在控制台中打印一个字符串:1->2->3。这是我的密码: class MyThread { public Thread Thrd; static Semaphore sem = new Semaphore(1, 1); static int flag = 1; public MyThread(string name) { Thrd = new Thr

我尝试使用
Semaphore
class同步三个线程(名为“1”、“2”和“3”)。他们必须在控制台中打印一个字符串:1->2->3。这是我的密码:

class MyThread
{
    public Thread Thrd;
    static Semaphore sem = new Semaphore(1, 1);
    static int flag = 1;

    public MyThread(string name)
    {
        Thrd = new Thread(this.Run);
        Thrd.Name = name;
        Thrd.Start();
    }

    void Run()
    {
        sem.WaitOne();
        if (Convert.ToInt32(Thrd.Name) == flag)
        {
            Console.WriteLine("Thread " + Thrd.Name);
            flag++;
        }
        if (flag == 4)
            flag = 1;
        Thread.Sleep(300);
        sem.Release();
    }
}

class SemaphoreDemo
{
    static void Main()
    {
        for (int i = 0; i < 10; i++)
        {
            MyThread mt1 = new MyThread("1");
            MyThread mt2 = new MyThread("2");
            MyThread mt3 = new MyThread("3");

            mt1.Thrd.Join();
            mt2.Thrd.Join();
            mt3.Thrd.Join();
        }
    }
}
类读取
{
公共线程Thrd;
静态信号量sem=新信号量(1,1);
静态int标志=1;
公共MyThread(字符串名称)
{
Thrd=新线程(this.Run);
Thrd.Name=名称;
Thrd.Start();
}
无效运行()
{
sem.WaitOne();
if(Convert.ToInt32(Thrd.Name)==标志)
{
控制台写入线(“线程”+Thrd.Name);
flag++;
}
如果(标志==4)
flag=1;
睡眠(300);
sem.Release();
}
}
类信号量
{
静态void Main()
{
对于(int i=0;i<10;i++)
{
MyThread mt1=新的MyThread(“1”);
MyThread mt2=新的MyThread(“2”);
MyThread mt3=新的MyThread(“3”);
mt1.Thrd.Join();
mt2.Thrd.Join();
mt3.Thrd.Join();
}
}
}
但有时看不到线程#2和#3的字符串。我的错误在哪里?如何解决此问题


多谢各位

问题在于,有时线程会无序获取信号量,而您没有任何重试逻辑。看看你的
Run
方法

void Run()
{
    sem.WaitOne();
    if (Convert.ToInt32(Thrd.Name) == flag)
    {
        Console.WriteLine("Thread " + Thrd.Name);
        flag++;
    }
    if (flag == 4)
        flag = 1;
    Thread.Sleep(300);
    sem.Release();
}
现在,如果名为“3”的线程首先获取信号量,会发生什么<代码>标志等于
1
,因此条件代码不会执行。线程将只休眠300毫秒,然后退出。如果要使其工作,必须使线程重试:

void Run()
{
    bool success = false;
    while (!success)
    {
        sem.WaitOne();
        if (Convert.ToInt32(Thrd.Name) == flag)
        {
            Console.WriteLine("Thread " + Thrd.Name);
            flag++;
            success = true;
        }
        sem.Release();
        if (!success)
        {
            // let somebody else try
            Thread.Sleep(300);
        }
    }
}
这将使你的样品按预期工作

我怀疑这只是一个了解线程和信号量如何工作的练习。然而,请注意,互斥通常比最大计数为1的信号量更合适

另外请注意,还有其他方法可以使线程按顺序执行,不过如果您要按顺序执行线程,那么您可能不需要多个线程。除非这些线程正在做其他事情,它们只需要排序一次——或者不经常排序