Jump to page: 1 2
Thread overview
Problems with Mutex
Oct 26, 2014
Neven
Oct 26, 2014
Damian
Oct 26, 2014
Neven
Oct 26, 2014
Damian
Oct 26, 2014
Damian
Oct 26, 2014
Neven
Oct 27, 2014
ketmar
Oct 27, 2014
ketmar
Oct 26, 2014
ketmar
Oct 27, 2014
ketmar
Oct 27, 2014
ketmar
Oct 27, 2014
Jonathan M Davis
Oct 28, 2014
Sean Kelly
October 26, 2014
I'm trying to use Mutex from core.sync.mutex; but when I try to initialize it at compile time this error pops up:

Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code

So I try to initialize it at run time but whenever I use that mutex in code (via synchronized blocks) I get segmetation faults (SIGSEGV).

Code here: http://pastebin.com/Z8Yj2kwY
October 26, 2014
On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
> I'm trying to use Mutex from core.sync.mutex; but when I try to initialize it at compile time this error pops up:
>
> Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code
>
> So I try to initialize it at run time but whenever I use that mutex in code (via synchronized blocks) I get segmetation faults (SIGSEGV).
>
> Code here: http://pastebin.com/Z8Yj2kwY

Try
__gshared Mutex mutex;
October 26, 2014
On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
> On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
>> I'm trying to use Mutex from core.sync.mutex; but when I try to initialize it at compile time this error pops up:
>>
>> Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code
>>
>> So I try to initialize it at run time but whenever I use that mutex in code (via synchronized blocks) I get segmetation faults (SIGSEGV).
>>
>> Code here: http://pastebin.com/Z8Yj2kwY
>
> Try
> __gshared Mutex mutex;

Thanks, that works now; but why?

Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?
October 26, 2014
On Sunday, 26 October 2014 at 22:53:09 UTC, Neven wrote:
> On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
>> On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
>>> I'm trying to use Mutex from core.sync.mutex; but when I try to initialize it at compile time this error pops up:
>>>
>>> Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code
>>>
>>> So I try to initialize it at run time but whenever I use that mutex in code (via synchronized blocks) I get segmetation faults (SIGSEGV).
>>>
>>> Code here: http://pastebin.com/Z8Yj2kwY
>>
>> Try
>> __gshared Mutex mutex;
>
> Thanks, that works now; but why?
>
> Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?

You can use auto mutex = cast(shared)(new Mutex());
October 26, 2014
On Sunday, 26 October 2014 at 22:53:09 UTC, Neven wrote:
> On Sunday, 26 October 2014 at 22:21:17 UTC, Damian wrote:
>> On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:
>>> I'm trying to use Mutex from core.sync.mutex; but when I try to initialize it at compile time this error pops up:
>>>
>>> Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code
>>>
>>> So I try to initialize it at run time but whenever I use that mutex in code (via synchronized blocks) I get segmetation faults (SIGSEGV).
>>>
>>> Code here: http://pastebin.com/Z8Yj2kwY
>>
>> Try
>> __gshared Mutex mutex;
>
> Thanks, that works now; but why?
>
> Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?

Globally you can use:

Mutex mutex;

static this()
{
  mutex = new Mutex();
}
October 26, 2014
On Sun, 26 Oct 2014 22:53:07 +0000
Neven via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?
this is because 'auto mutex = new Mutex' is not a global declaration, it's thread-local declaration. all D variables are thread-locals by default.

i.e. you have one indepented Mutex for each thread. and you initialized it only in one thread, all other threads got unitialized Mutex objects.

having thread-locals instead of globals by default can be confusing if you missed that in documentation. just use 'shared' or '__gshared' to get "real" globals.


October 26, 2014
@Damian
> You can use auto mutex = cast(shared)(new Mutex());

Not working;  Error: constructor core.sync.mutex.Mutex.this core.sync.mutex.Mutex cannot be constructed at compile time, because the constructor has no available source code

>Mutex mutex;
>static this()
>{
>  mutex = new Mutex();
>}

I have synchronization problems with this one. Even when I prepend __gshared Mutex mutex in this case.

Changed code: http://pastebin.com/KmxCemn3
Output: http://pastebin.com/zFFLnCTD
As you can see beginning is not what I expect to get.

@ketmar
> having thread-locals instead of globals by default can be confusing if
you missed that in documentation. just use 'shared' or '__gshared' to
get "real" globals.

Thank you for clearing this up. If I understand correctly, __gshared is more of a hack to get C-like global variables, whilst shared is typed shared variable and more preferred?
October 27, 2014
On Sun, 26 Oct 2014 23:37:25 +0000
Neven via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> >Mutex mutex;
> >static this()
> >{
> >  mutex = new Mutex();
> >}
> 
> I have synchronization problems with this one. Even when I prepend __gshared Mutex mutex in this case.
ah, there is another subtle thing. 'static this()' will be called for each new thread, so what you actually doing is creating new mutex object when each thread started. it's the same thing as with globals vs thread-locals. what you really want in this case is 'global initializer', which will be called once on program startup. to achieve this you have to write:

  shared static this () {
    mutex = new Mutex();
  }

'shared static this()' will be called only once.

> Thank you for clearing this up. If I understand correctly, __gshared is more of a hack to get C-like global variables, whilst shared is typed shared variable and more preferred?
yes and no. 'shared' is the part of the type, while '__gshared' is not. i.e.

  shared int a;
  pragma(msg, typeof(a)); // this will print "shared(int)"

  __gshared int b;
  pragma(msg, typeof(b)); // this will print "int"

you can't freely mix shared and non-shared types, so you must cast 'shared' away on occasion and cast it back when necessary. this is not safe and error-prone.

'__gshared', for the other side, doesn't influence the type, so you can have global variable which can be passed to other functions without casting.

but yes, generally this is a hack, and you'd better avoid '__gshared' in idiomatic D code unless you are really really know what you are doing and what consequences it may have. ;-)


October 27, 2014
On Mon, 27 Oct 2014 02:07:09 +0200
ketmar via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> > Thank you for clearing this up. If I understand correctly, __gshared is more of a hack to get C-like global variables, whilst shared is typed shared variable and more preferred?
> yes and no. 'shared' is the part of the type, while '__gshared' is not. i.e.
> 
>   shared int a;
>   pragma(msg, typeof(a)); // this will print "shared(int)"
> 
>   __gshared int b;
>   pragma(msg, typeof(b)); // this will print "int"
> 
> you can't freely mix shared and non-shared types, so you must cast 'shared' away on occasion and cast it back when necessary. this is not safe and error-prone.
> 
> '__gshared', for the other side, doesn't influence the type, so you can have global variable which can be passed to other functions without casting.
> 
> but yes, generally this is a hack, and you'd better avoid '__gshared' in idiomatic D code unless you are really really know what you are doing and what consequences it may have. ;-)
here is some silly code to show you some difference between 'shared' and '__gshared':

  void foo (ref int i) {}

  int a;
  shared int b;
  __gshared int c;

  void main () {
    foo(a); // this compiles
    foo(b); // this will not compile (see below)
    foo(c); // this compiles too
  }

`foo(b);` will not compile, compiler emits error:
"Error: function y01.foo (ref int i) is not callable using argument
types (shared(int))"

if you'll change `foo` to `void foo (ref shared int i) {}`, you'll get
the opposite: `foo(a)` and `foo(c)` will be refused by compiler.


October 27, 2014
On 10/26/14 7:13 PM, ketmar via Digitalmars-d-learn wrote:
> On Sun, 26 Oct 2014 22:53:07 +0000
> Neven via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
>> Why cannot I globally have auto mutex = new Mutex? And why it
>> works now when I put __gshared?
> this is because 'auto mutex = new Mutex' is not a global declaration,
> it's thread-local declaration. all D variables are thread-locals by
> default.
>
> i.e. you have one indepented Mutex for each thread. and you initialized
> it only in one thread, all other threads got unitialized Mutex objects.
>
> having thread-locals instead of globals by default can be confusing if
> you missed that in documentation. just use 'shared' or '__gshared' to
> get "real" globals.
>

Just as a followup, for some reason Mutex is not callable as a shared object, so you have to make it __gshared.

This is unfortunate, but it is the only way to do it right now. Because an actual mutex is thread safe, it is not a problem.

-Steve
« First   ‹ Prev
1 2