队列上的竞争条件

发布于 2024-12-11 07:17:57 字数 917 浏览 0 评论 0原文

下面的代码处理带有 2 个参数的套接字消息。它将信息放入队列中并在另一个线程上进行处理。我的问题是,如果两条消息紧接着另一条消息进入,然后出队并发送到 ProcessData 方法,那么 ProcessData 上是否存在竞争条件?

private void DataIn(long Code, string Message)
{
  if (!Started)
  {
    if (DataInQueue == null)
      DataInQueue = new Queue();
    DataInThread = new Thread(new ThreadStart(ThreadProcedure));
    DataInThreadEnding = false;
    DataInThread.IsBackground = true;
    DataInThread.Start();
    Started = true;
  }
  DataInQueue.Enqueue(new cDataIn(Code, Message));
}

private void ThreadProcedure()
{
   while (!ProgramEnding)
   {
     Queue mySyncdQ = Queue.Synchronized(DataInQueue);
     if (mySyncdQ != null && mySyncdQ.Count > 0)
     {
        cDataIn data = null;
        // Creates a synchronized wrapper around the Queue. 
        if (mySyncdQ.Count > 0)
          data = (cDataIn)mySyncdQ.Dequeue();

        ProcessData(data);
    }
  }

}

The below code handles a socket message coming in with a 2 parameters. It puts information into a queue and is processed on another thread. My question is if 2 messages come in right after the other and are then dequeued and sent to the method ProcessData, is there a race condition on ProcessData?

private void DataIn(long Code, string Message)
{
  if (!Started)
  {
    if (DataInQueue == null)
      DataInQueue = new Queue();
    DataInThread = new Thread(new ThreadStart(ThreadProcedure));
    DataInThreadEnding = false;
    DataInThread.IsBackground = true;
    DataInThread.Start();
    Started = true;
  }
  DataInQueue.Enqueue(new cDataIn(Code, Message));
}

private void ThreadProcedure()
{
   while (!ProgramEnding)
   {
     Queue mySyncdQ = Queue.Synchronized(DataInQueue);
     if (mySyncdQ != null && mySyncdQ.Count > 0)
     {
        cDataIn data = null;
        // Creates a synchronized wrapper around the Queue. 
        if (mySyncdQ.Count > 0)
          data = (cDataIn)mySyncdQ.Dequeue();

        ProcessData(data);
    }
  }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淑女气质 2024-12-18 07:17:57

UPDATE

Queue 在您的代码中未以线程安全的方式使用...您显示的代码不足以确定是否存在竞争条件,但使用 ConcurrentQueue 您可以获得更好的性能。 ..并且在 ThreadProcedure 中,您可以使用 null 调用 ProcessData,据我所知,为了安全起见,ProcessData 应该是可重入的,以便所有这些都能正常工作...

使用 ConcurrentQueue - 避免了一些可能的问题...并查看 BlockingCollection 其设计对于线程安全的生产者/消费者场景...两者都主要无锁工作并且非常快...

UPDATE

Queue is not used in a thread-safe manner in your code... the code you show is not enough to be sure whether there is a race condition but with the ConcurrentQueue you get a better performance... and in the ThreadProcedure you can have calling ProcessData with null and as far as I can tell to be on the safe side ProcessData should be reentrant for all this to work...

Use a ConcurrentQueue - that avoids some possible problems... and check out BlockingCollection which is designed for thread-safe Producer/Consumer scenarios... both work mostly lock-free and are really fast...

小糖芽 2024-12-18 07:17:57

是的,我认为这甚至会使您的队列处于不稳定状态。您应该使用 并发队列 BlockingCollection 随 .Net 4 一起提供。线程安全开箱即用并经过优化。

问候格特-扬

Yes I think this can even leave your Queue in an inconstistant state. You should use the Concurrent Queue BlockingCollection that ships with .Net 4. It's threadsafe out of the box and optimzed.

Regards Gert-Jan

清风疏影 2024-12-18 07:17:57

您的代码不是线程安全的。请注意 Queue.Synchronized( 的文档) )

为了保证Queue的线程安全,所有操作都必须仅通过此包装器完成。

您直接使用队列,因此代码不是线程安全的。要解决此问题,请始终仅使用返回的包装器,如文档所述。

或者,如果您使用的是 .Net 4,请使用 ConcurrentQueue

如果您想在 .Net 的早期版本上使用通用队列,则可以使用 Queue 并始终以的方式访问它。

Your code is not thread safe. Notice this in the documentation for Queue.Synchronized():

To guarantee the thread safety of the Queue, all operations must be done through this wrapper only.

You're using the queue directly, so the code is not thread-safe. To fix this, always use just the returned wrapper, as the documentation says.

Or, if you're under .Net 4, use ConcurrentQueue<T>.

If you wanted to use generic queue on an previous version of .Net, you would could use Queue<T> and always access it in a lock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文