队列上的竞争条件
下面的代码处理带有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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 outBlockingCollection
which is designed for thread-safe Producer/Consumer scenarios... both work mostly lock-free and are really fast...是的,我认为这甚至会使您的队列处于不稳定状态。您应该使用
并发队列BlockingCollection 随 .Net 4 一起提供。线程安全开箱即用并经过优化。问候格特-扬
Yes I think this can even leave your Queue in an inconstistant state. You should use the
Concurrent QueueBlockingCollection that ships with .Net 4. It's threadsafe out of the box and optimzed.Regards Gert-Jan
您的代码不是线程安全的。请注意 Queue.Synchronized( 的文档) ):
您直接使用队列,因此代码不是线程安全的。要解决此问题,请始终仅使用返回的包装器,如文档所述。
或者,如果您使用的是 .Net 4,请使用
ConcurrentQueue
。如果您想在 .Net 的早期版本上使用通用队列,则可以使用
Queue
并始终以锁
的方式访问它。Your code is not thread safe. Notice this in the documentation for
Queue.Synchronized()
: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 alock
.