Re: Thread safe



sagenaut@xxxxxxxxx wrote:
I have a monitor like class and a thread-safe queue:

....

Are the put() and get() thread safe? I used two locks for
serialization and one lock for signaling. This allows two threads
access to the queue: one for put and the other for get. Normal
implementation would use only one lock and allows only one thread to
access queue:

....


Which is the right way to implemt the put() and get()? Thanks in
advance.


You'd probably have to implement it both ways to determine whether it
makes a difference. However, if you use separate mutexes for put and
get, you need to use a common mutex to synchronize memory state, not
just for signaling. Use two queues, one for gets and the other for
puts. Move the entire put queue to the get queue when the latter is
empty.

T * get() {
getLock.lock();
if (queue0.empty() {
putLock.lock();
while (queue0.empty() && queue1.empty()) putLock.wait();
queue0.append(queue1); // append all of queue1 onto queue0
putLock.unlock();
}
T * tmp = queue0.pop();
getLock.unlock;
return tmp;
}

void put(T * item) {
putLock.lock();
if (queue1.empty() putLock.broadcast();
queue1.push(item);
putLock.unlock();
}


Of course if the queues are empty most of the time, this will have
slightly more overhead than using a single lock.

And if lock contention is the problem, this would only cut contention
in half. Lock-free would probably be the better way to qo.



--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software. .



Relevant Pages

  • Re: Seeing lock order reversal
    ... 21 vm page queue free mutex -- ... 18 UMA zone -- ... 18 sleep mtxpool -- ... 15 process lock -- ...
    (freebsd-current)
  • Re: Thread safe
    ... serialization and one lock for signaling. ... access to the queue: one for put and the other for get. ... And if lock contention is the problem, ...
    (comp.programming.threads)
  • Re: location of bioq lock
    ... queue is owned by the driver, and the locking scheme remains the same. ... from a different scheduler than the default, it can be easily plugged in. ... process you have to lock each queue before playing with it. ...
    (freebsd-current)
  • Re: thread communication
    ... I changed this into a simple class which has a SyncRoot which I can Wait and Pulse, and then some code to process the queue. ... One thing I noticed in your code though, in your desire to move the actual processing outside of the lock, you have introduced an inefficiency in the synchronization. ... IFileProcessor processor = Queue.Dequeue; ... Especially with the above alternative, you could easily maintain a local Queue to which all of the public Queue elements are copied, and then just loop while unlocked until the local Queue is empty, adding the "ready" items back into the local Queue as you find them. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: thread-safety
    ... but that would depend on the implementation of your Queue class. ... lock { ... It's odd for you to be passing a WaitHandle of any sort to the Monitor class; if you've got a WaitHandle, you would normally just wait on _that_, rather than using the WaitHandle simply as a synchronization object for Monitor. ... It would be a problem to call Monitor.Pulseif no other thread is waiting at a call to Monitor.Wait, because then the waiting thread would miss the Pulse. ...
    (microsoft.public.dotnet.languages.csharp)