【问题标题】:Synchronization with semaphore与信号量同步
【发布时间】:2014-06-11 22:25:51
【问题描述】:

我尝试使用Semaphore 类同步三个线程(名为“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();
        }
    }
}

但有时看不到来自线程#2 和#3 的字符串。我的错误在哪里,我该如何解决这个问题?

非常感谢!

【问题讨论】:

    标签: c# multithreading synchronization


    【解决方案1】:

    问题是有时线程会乱序获取信号量,而您没有任何重试逻辑。看看你的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”的线程首先获取信号量会发生什么? flag 等于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);
            }
        }
    }
    

    这将使您的示例按预期工作。

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

    还请注意,还有其他方法可以使线程按顺序执行,但说实话,如果您要对线程进行排序,那么您可能不需要多个线程。除非这些线程正在做其他事情,并且它们只需要排序一次——或者很少。

    【讨论】:

      猜你喜欢
      • 2013-05-30
      • 2018-09-25
      • 1970-01-01
      • 2011-07-02
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多