June 27, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | "Walter Bright" <newshound1@digitalmars.com> wrote in message news:g3uqph$2s3n$1@digitalmars.com... > Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement. > > Does anyone write threading code that depends on this behavior? Never understood that one, so: no. But I do think there's a place for synchronized { }: memory barrier. IIRC a mutex always implies a memory barrier anyway. synchronized without argument could only create a memory barrier. This could then be used to achieve what the Interlocked* functions in Win32 do. It's such a basic operation that I think it warrants a language construct. static int b;//some global int a;//local // native cross-platform InterlockedIncrement synchronized { a = b++; } I should note however that I'm currently having a hard-time implementing some multi-threaded algorithms.. I probably don't know enough about MT to be messing with it :S L. | |||
June 27, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to cemiller | "cemiller" wrote
> On Thu, 26 Jun 2008 16:42:32 -0700, BCS wrote:
>
>> Reply to cemiller,
>>
>>> I use it on occasion. It can be useful for singleton:
>>> if(!foo)
>>> {
>>> synchronized
>>> {
>>> if(!foo)
>>> foo = new Foo();
>>> }
>>> }
>>> return foo;
>>> especially useful because you don't need an object instance.
>>>
>>
>> Hmmm. Slight variation on my last suggestion, Allow synchronized to take any global symbol as the mutex
>>
>> if(!foo)
>> {
>> synchronized(Foo) // global mutex on Foo
>> {
>> if(!foo)
>> foo = new Foo();
>> }
>> }
>>
>> Or if you need more resolution:
>>
>> class Foo
>> {
>> alias void single;
>> }
>>
>> ...
>> synchronized(Foo.single) // global mutex on Foo.single
>> ...
>
>
> I could synchronized(typeid(Foo)) but I don't think D guarantees that each type has its own instance and monitor. This could potentially be a substitute; create a type and lock on it, no runtime allocation, not many language changes needed.
I think this is guaranteed as long as you are not loading D from multiple DLLs.
In any case, Tango avoids needing this statement by making mutexes fully accessible objects. If you need a mutex without having it attached to an object, it's easy:
Mutex m = new Mutex;
synchronized(m)
{
}
-Steve
| |||
June 27, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> In any case, Tango avoids needing this statement by making mutexes fully accessible objects. If you need a mutex without having it attached to an object, it's easy:
>
> Mutex m = new Mutex;
>
> synchronized(m)
> {
> }
Isn't that the same as doing this?
---
Object m = new Object;
synchronized(m)
{
}
---
| |||
June 27, 2008 A quick way to replicate the old behavior using synchronized(Object) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | gentoo-pc ~ $ cat test50.d; echo "==="; gdc test50.d -o test50 && ./test5
0
import std.stdio;
template _SyncObject(string KEY) {
Object obj;
static this() { obj = new Object; }
}
template SyncObject(string KEY) {
alias _SyncObject!(KEY).obj SyncObject;
}
void main() {
writefln(SyncObject!("main_1") is SyncObject!("main_1"));
writefln(SyncObject!("main_1") !is SyncObject!("main_2"));
synchronized (SyncObject!("main_1")) {
writefln("Test");
}
}
===
true
true
Test
| |||
June 27, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to torhu | "torhu" wrote
> Steven Schveighoffer wrote:
>> In any case, Tango avoids needing this statement by making mutexes fully accessible objects. If you need a mutex without having it attached to an object, it's easy:
>>
>> Mutex m = new Mutex;
>>
>> synchronized(m)
>> {
>> }
>
>
> Isn't that the same as doing this?
>
> ---
> Object m = new Object;
>
> synchronized(m)
> {
> }
It's close, but in Tango, you have methods for the mutex, plus you can use them with conditions.
Plus, it's not as hackish :)
It would be nice if the language supported conditions based on the Monitor object by default.
-Steve
| |||
June 28, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
>
> Does anyone write threading code that depends on this behavior?
Slightly off topic.
Just a thought. If we had the ability to do block operators, or turn functions with delegates into blocks, or any other incarnation we could have this as a library function.
-Joel
| |||
June 29, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | == Quote from Walter Bright (newshound1@digitalmars.com)'s article
> Right now, if you use a synchronized statement with no argument, it will
> sync on a mutex unique to that statement.
> Does anyone write threading code that depends on this behavior?
It's certainly convenient in some instances, but obviously not necessary. Still, I find the current behavior to be easily understandable.
Sean
| |||
June 29, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | On Thu, 26 Jun 2008 08:15:24 -0400, Michel Fortin wrote:
> On 2008-06-25 21:18:41 -0400, Walter Bright <newshound1@digitalmars.com> said:
>
>> Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
>>
>> Does anyone write threading code that depends on this behavior?
>
> I've used it before, thinking it was equivalent to synchronize(this) {}, an incorrect assumption obviously. If you get rid of it, I won't miss it.
Same.
| |||
June 30, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to torhu | == Quote from torhu (no@spam.invalid)'s article
> Steven Schveighoffer wrote:
> > In any case, Tango avoids needing this statement by making mutexes fully accessible objects. If you need a mutex without having it attached to an object, it's easy:
> >
> > Mutex m = new Mutex;
> >
> > synchronized(m)
> > {
> > }
> Isn't that the same as doing this?
> ---
> Object m = new Object;
> synchronized(m)
> {
> }
> ---
No. Mutexes in Tango can be set as the monitor for any object, and are in fact their own monitors. So synchronized(m) actually locks the Mutex, not a separate monitor object associated with the Mutex object. You can just as easily do this:
class C
{
this(Mutex x)
{
m = x;
setMonitor(this, m);
}
Mutex m;
void fn()
{
// the following are all equivalent
synchronized {}
synchronized(this) {}
synchronized(m) {}
}
}
Ore read-write mutexes:
ReadWriteMutex m;
synchronized(m.reader) {}
synchronized(m.writer) {}
Sean
| |||
June 30, 2008 Re: synchronized { } | ||||
|---|---|---|---|---|
| ||||
Posted in reply to janderson | == Quote from janderson (askme@me.com)'s article
> Walter Bright wrote:
> > Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
> >
> > Does anyone write threading code that depends on this behavior?
> Slightly off topic.
> Just a thought. If we had the ability to do block operators, or turn
> functions with delegates into blocks, or any other incarnation we could
> have this as a library function.
It is already effectively a library function in Tango. Tango contains mutexes
which may operate as object monitors and there is no real code dependency
for this between the runtime and library code.
Sean
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply