Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 26, 2012 [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Hi,
What's with the weird, convoluted way one is supposed to use core.sync.condition.Condition? Having to lock on a mutex while using a Condition object is extremely weird compared to APIs in other programming languages. Any particular reason behind this design?
Regards,
Alex
_______________________________________________
D-runtime mailing list
D-runtime@puremagic.com
http://lists.puremagic.com/mailman/listinfo/d-runtime
|
April 25, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Thursday, April 26, 2012 00:41:40 Alex Rønne Petersen wrote: > Hi, > > What's with the weird, convoluted way one is supposed to use core.sync.condition.Condition? Having to lock on a mutex while using a Condition object is extremely weird compared to APIs in other programming languages. Any particular reason behind this design? Really? In C++, from what I've seen, you always end up locking on a mutex to protect a condition variable. How could it work _without_ locking? The condition variable wouldn't be protected against multiple threads using it. - Jonathan M Davis _______________________________________________ D-runtime mailing list D-runtime@puremagic.com http://lists.puremagic.com/mailman/listinfo/d-runtime |
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Surely it could lock whatever it needs to lock internally? See: http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx That class is entirely thread safe. Regards, Alex On Thu, Apr 26, 2012 at 1:17 AM, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > On Thursday, April 26, 2012 00:41:40 Alex Rønne Petersen wrote: >> Hi, >> >> What's with the weird, convoluted way one is supposed to use core.sync.condition.Condition? Having to lock on a mutex while using a Condition object is extremely weird compared to APIs in other programming languages. Any particular reason behind this design? > > Really? In C++, from what I've seen, you always end up locking on a mutex to protect a condition variable. How could it work _without_ locking? The condition variable wouldn't be protected against multiple threads using it. > > - Jonathan M Davis > _______________________________________________ > D-runtime mailing list > D-runtime@puremagic.com > http://lists.puremagic.com/mailman/listinfo/d-runtime _______________________________________________ D-runtime mailing list D-runtime@puremagic.com http://lists.puremagic.com/mailman/listinfo/d-runtime |
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen Attachments:
| A condition variable is logically attached to an arbitrary condition as defined in your code (such as, there is an element in a queue). The proper sequence for using a condition is:
lock(mutex);
while(logicalConditionIsFalse) cond.wait();
// processCondition, e.g. remove element from queue
unlock(mutex);
It doesn't work like an event in Windows, and events in windows do *not* protect external conditions, the event *is* the condition.
For mutex/conditions, only threads waiting *at the time* you signal a condition will be woken up. So you have to have a mutex to protect the state of the condition, otherwise, you might miss the condition signal. You also avoid needless waiting/locking.
You might build mutex/conditions into a more high-level object (such as a queue), which would hide the details, but the primitives are correct, and time-tested.
Now, I'm all for a use case of storing the mutex in the condition and having the condition "own" the mutex, but that should not be a limitation, you should be able to attach multiple conditions to the same mutex, which means none of them own it.
-Steve
>________________________________
> From: Alex Rønne Petersen <xtzgzorex@gmail.com>
>To: D's runtime library developers list <d-runtime@puremagic.com>
>Sent: Wednesday, April 25, 2012 8:18 PM
>Subject: Re: [D-runtime] What's with core.sync.condition usage?
>
>Surely it could lock whatever it needs to lock internally?
>
>See: http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
>
>That class is entirely thread safe.
>
>Regards,
>Alex
>
>On Thu, Apr 26, 2012 at 1:17 AM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
>> On Thursday, April 26, 2012 00:41:40 Alex Rønne Petersen wrote:
>>> Hi,
>>>
>>> What's with the weird, convoluted way one is supposed to use core.sync.condition.Condition? Having to lock on a mutex while using a Condition object is extremely weird compared to APIs in other programming languages. Any particular reason behind this design?
>>
>> Really? In C++, from what I've seen, you always end up locking on a mutex to protect a condition variable. How could it work _without_ locking? The condition variable wouldn't be protected against multiple threads using it.
>>
>> - Jonathan M Davis
>> _______________________________________________
>> D-runtime mailing list
>> D-runtime@puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/d-runtime
>_______________________________________________
>D-runtime mailing list
>D-runtime@puremagic.com
>http://lists.puremagic.com/mailman/listinfo/d-runtime
>
>
>
|
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | On Apr 26, 2012, at 7:50 AM, Steve Schveighoffer wrote: > > Now, I'm all for a use case of storing the mutex in the condition and having the condition "own" the mutex, but that should not be a limitation, you should be able to attach multiple conditions to the same mutex, which means none of them own it. I remember you saying that Condition should have a mutex() property, and then I forgot to add it. I think I'll take care of that today. _______________________________________________ D-runtime mailing list D-runtime@puremagic.com http://lists.puremagic.com/mailman/listinfo/d-runtime |
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | On Apr 26, 2012, at 7:50 AM, Steve Schveighoffer wrote: > A condition variable is logically attached to an arbitrary condition as defined in your code (such as, there is an element in a queue). The proper sequence for using a condition is: > > lock(mutex); > while(logicalConditionIsFalse) cond.wait(); > // processCondition, e.g. remove element from queue > unlock(mutex); > > It doesn't work like an event in Windows, and events in windows do *not* protect external conditions, the event *is* the condition. > > For mutex/conditions, only threads waiting *at the time* you signal a condition will be woken up. So you have to have a mutex to protect the state of the condition, otherwise, you might miss the condition signal. You also avoid needless waiting/locking. > > You might build mutex/conditions into a more high-level object (such as a queue), which would hide the details, but the primitives are correct, and time-tested. > > Now, I'm all for a use case of storing the mutex in the condition and having the condition "own" the mutex, but that should not be a limitation, you should be able to attach multiple conditions to the same mutex, which means none of them own it. This is exactly right, by the way. Windows events are difficult to use correctly/efficiently because there's no way to atomically associate state checking with wakeup events. Condition variables themselves are simpler because all they do is communicate the wakeup event, leaving all state checking up to the user. They work because the transition from holding a lock on the mutex to waiting on the condition is logically atomic, as is the transition from notification to re-acquiring the mutex. The general producer/consumer model with conditions is: void put(T val) { synchronized (cond.mutex) { queue.pushBack(val); cond.notify(); // atomically unlocks mutex on call, locks on return } } T get() { synchronized (cond.mutex) { while (list.isEmpty) cond.wait(); // atomically unlocks mutex on call, locks on return return queue.popFront(); } } The loop is required because it's possible that a thread waiting on the condition could wake up accidentally (say from a signal), so there's no 100% guarantee that there will actually be something in the queue. The really nice thing about conditions is that the state checking can be as complex as you want, and you can have multiple conditions for the same mutex. _______________________________________________ D-runtime mailing list D-runtime@puremagic.com http://lists.puremagic.com/mailman/listinfo/d-runtime |
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly Attachments:
|
>________________________________
> From: Sean Kelly <sean@invisibleduck.org>
>void put(T val) {
> synchronized (cond.mutex) {
> queue.pushBack(val);
> cond.notify(); // atomically unlocks mutex on call, locks on return
> }
>}
>Huh, I thought notify did not unlock the mutex at all (I don't see why it would need to).
-Steve
|
April 26, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | On Apr 26, 2012, at 1:22 PM, Steve Schveighoffer wrote: > > From: Sean Kelly <sean@invisibleduck.org> > void put(T val) { > synchronized (cond.mutex) { > queue.pushBack(val); > cond.notify(); // atomically unlocks mutex on call, locks on return > } > } > Huh, I thought notify did not unlock the mutex at all (I don't see why it would need to). Oops… you're right. The original implementation (Hoare's) did, I believe, but the modern one does not. _______________________________________________ D-runtime mailing list D-runtime@puremagic.com http://lists.puremagic.com/mailman/listinfo/d-runtime |
April 27, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly Attachments:
| Now I'm really confused.
How is this thing *actually* supposed to be used? And can we add some examples to the docs?
Regards,
Alex
On Fri, Apr 27, 2012 at 1:08 AM, Sean Kelly <sean@invisibleduck.org> wrote:
> On Apr 26, 2012, at 1:22 PM, Steve Schveighoffer wrote:
> >
> > From: Sean Kelly <sean@invisibleduck.org>
> > void put(T val) {
> > synchronized (cond.mutex) {
> > queue.pushBack(val);
> > cond.notify(); // atomically unlocks mutex on call, locks on
> return
> > }
> > }
> > Huh, I thought notify did not unlock the mutex at all (I don't see why
> it would need to).
>
> Oops… you're right. The original implementation (Hoare's) did, I believe,
> but the modern one does not.
> _______________________________________________
> D-runtime mailing list
> D-runtime@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/d-runtime
>
|
April 27, 2012 Re: [D-runtime] What's with core.sync.condition usage? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen Attachments:
| Just like Sean said. It's just his comment that puzzled me.
Examples would be nice. I've done an article in the past on thread programming, maybe I'll do something for this. If you search google for mutex condition, I'm sure you'll find loads of examples.
-Steve
>________________________________
> From: Alex Rønne Petersen <xtzgzorex@gmail.com>
>To: D's runtime library developers list <d-runtime@puremagic.com>
>Sent: Thursday, April 26, 2012 7:10 PM
>Subject: Re: [D-runtime] What's with core.sync.condition usage?
>
>
>Now I'm really confused.
>
>
>How is this thing *actually* supposed to be used? And can we add some examples to the docs?
>
>
>Regards,
>Alex
>
>
>On Fri, Apr 27, 2012 at 1:08 AM, Sean Kelly <sean@invisibleduck.org> wrote:
>
>On Apr 26, 2012, at 1:22 PM, Steve Schveighoffer wrote:
>>>
>>> From: Sean Kelly <sean@invisibleduck.org>
>>> void put(T val) {
>>> synchronized (cond.mutex) {
>>> queue.pushBack(val);
>>> cond.notify(); // atomically unlocks mutex on call, locks on return
>>> }
>>> }
>>> Huh, I thought notify did not unlock the mutex at all (I don't see why it would need to).
>>
>>Oops… you're right. The original implementation (Hoare's) did, I believe, but the modern one does not.
>>
>>_______________________________________________
>>D-runtime mailing list
>>D-runtime@puremagic.com
>>http://lists.puremagic.com/mailman/listinfo/d-runtime
>>
>
>_______________________________________________
>D-runtime mailing list
>D-runtime@puremagic.com
>http://lists.puremagic.com/mailman/listinfo/d-runtime
>
>
>
|
Copyright © 1999-2021 by the D Language Foundation