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 assigning queue1
to queue2
does only copy the reference, not the queue itself.
The assignment itself is atomic and thus thread-safe. Accessing queue1
in one thread, and queue2
in another is no safer that accessing queue1
from both of them. i.e. it is unsafe.
I believe ConcurrentQueue<T>
uses "lockless" programming techniques (Interlocked.Exchange
and 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 using ConcurrentQueue<T>
.
On my 2.6GHz system ConcurrentQueue<object>
manages 15 million enqueue/dequeue pairs per second compared to 40 million with with Queue<object>
. So Queue<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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With