【问题标题】:C# I need to allow The First thread to reach a certian point prevents other threads from continuingC#我需要允许第一个线程到达某个点阻止其他线程继续
【发布时间】:2013-09-01 01:24:27
【问题描述】:

我有多个线程在同一个线程安全函数上工作。经过 X 次迭代后,第一个到达 firstThread() 的线程将执行 firstThread() 并阻止其他线程继续执行,直到线程完成 firstThread()。只有第一个到达 firstThread() 的线程会执行其他线程不会。有点像一场比赛,第一个到达终点线的人就是赢家。在 firstThread() 完成后,所有线程都会继续,直到再次达到限制。有没有人有任何想法来实现这一点,将不胜感激。

    private void ThreadBrain()
    {
        Thread[] tList = new Thread[ThreadCount];
        sw.Start();

        for (int i = 0; i < tList.Length; i++)
        {
            tList[i] = new Thread(ThProc);
            tList[i].Start();
        }

        foreach (Thread t in tList)
            if (t != null) t.Join();





    }
    private void ThProc()
    {

            doWork();



    }
   private void firstThread()
   {
    //do some work
  loopCount=0;
  }

    private void doWork()
    {
//do some work
    loopCount++;
     //first thread to reach this point calls firstThread() and prevent other threads from continuing until current thread completes firstThread()
     If(loopCount>=loopLimit)firstThread()
}

【问题讨论】:

  • if (t != null) t.Join(); 中,if 部分没用。在 C# 中,如果 new 失败,它将引发异常。 new 没有静默失败。

标签: c# multithreading


【解决方案1】:

这样就可以了。只有第一个进入的线程会将OnlyFirst 从 0 更改为 1,并从 Interlocked.CompareExchange 接收 0。其他线程将失败并从Interlocked.CompareExchangereturn 接收 1。

private int OnlyFirst = 0;

private void doWork()
{
    if (Interlocked.CompareExchange(ref OnlyFirst, 1, 0) != 0)
    {
        return;
    }

【讨论】:

  • 我假设 OP 也想要一个同步屏障。
  • @Douglas 没用...第一个进入的线程会“连贯地”看到它的内存,而其他线程还没有完成,所以没有从第一个线程的 POV 保证它们处于一致状态。
  • 我的意思是“synchronization barrier”,而不是“内存屏障”。但是,在重新阅读问题后,我认为他们要求的不是障碍;相反,他们只需要一个关键部分。
【解决方案2】:
// Flag that will only be "true" for the first thread to enter the method.
private bool isFirstThread = true;

// The "Synchronized" option ensures that only one thread can execute the method
// at a time, with the others getting temporarily blocked.
[MethodImplOptions.Synchronized]
private void firstThread()
{
    if (isFirstThread)
    {
        //do some work
        loopCount=0;

        isFirstThread = false;
    }
}

【讨论】:

  • 根据 OP 的要求,你可以使用Monitor.TryLock,这样其他线程就可以死掉了。
  • 我已经回滚到我的第一个答案(没有明确使用Monitor)。
猜你喜欢
  • 1970-01-01
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多