I have generic Queue<T> (System.Collections.Generic) which is accessed for writing from one thread. And it must be accessed from another thread for reading.
I don’t want to do any process synchronization (which includes using ConcurrentQueue<T>) for performance reasons. So I came up with idea to copy the entire queue to another queue object of same type in the reading thread. Subsequent operations in the reading thread will be done on the copy. Copying will be done with simple operator =.
Here is some pseudo-code:
//Creating main queue
Queue<MyType> queue1 = new Queue<MyType>();
Writing thread:
//Perform writing in the main queue
queue1.Enqueue(object);
...
queue1.Dequeue();
Reading thread:
//Copy main queue
Queue<MyType> queue2 = queue1;
//perform all operations in reading thread on queue2
So is such solution thread safe?
UPD: Thank you very much, I wasn’t aware that this is merely copying of the link. So Is there a way to copy entire object by value in thread-safe manner?
Queue<T>is a reference type. So assigningqueue1toqueue2does only copy the reference, not the queue itself.The assignment itself is atomic and thus thread-safe. Accessing
queue1in one thread, andqueue2in another is no safer that accessingqueue1from both of them. i.e. it is unsafe.I believe
ConcurrentQueue<T>uses “lockless” programming techniques (Interlocked.Exchangeand friends) and is pretty fast. You should benchmark it first, before excluding it as a solution.Copying a
Queue<T>will certainly be slower than just usingConcurrentQueue<T>.On my 2.6GHz system
ConcurrentQueue<object>manages 15 million enqueue/dequeue pairs per second compared to 40 million with withQueue<object>. SoQueue<object>is about three times as fast.200 CPU cycles for an enqueue/dequeue pair is pretty cheap. If that is the bottleneck, try using more granular items in the queue.