digitalmars.D.learn - Problems with Mutex
- Neven (9/9) Oct 26 2014 I'm trying to use Mutex from core.sync.mutex; but when I try to
- Damian (3/12) Oct 26 2014 Try
- Neven (4/19) Oct 26 2014 Thanks, that works now; but why?
- Damian (2/22) Oct 26 2014 You can use auto mutex = cast(shared)(new Mutex());
- Damian (7/27) Oct 26 2014 Globally you can use:
- Neven (16/24) Oct 26 2014 Not working; Error: constructor core.sync.mutex.Mutex.this
- ketmar via Digitalmars-d-learn (27/38) Oct 26 2014 ah, there is another subtle thing. 'static this()' will be called for
- ketmar via Digitalmars-d-learn (19/42) Oct 26 2014 On Mon, 27 Oct 2014 02:07:09 +0200
- ketmar via Digitalmars-d-learn (10/12) Oct 26 2014 this is because 'auto mutex =3D new Mutex' is not a global declaration,
- Steven Schveighoffer (6/18) Oct 27 2014 Just as a followup, for some reason Mutex is not callable as a shared
- ketmar via Digitalmars-d-learn (8/10) Oct 27 2014 On Mon, 27 Oct 2014 09:24:13 -0400
- ketmar via Digitalmars-d-learn (10/15) Oct 27 2014 On Mon, 27 Oct 2014 09:24:13 -0400
- Steven Schveighoffer (8/23) Oct 27 2014 But the result is that you can't use a mutex embedded in a shared object...
- Jonathan M Davis via Digitalmars-d-learn (6/10) Oct 27 2014 The reason that it's not shared is because Sean Kelly didn't want to mak...
- Sean Kelly (7/12) Oct 28 2014 Yep. There was a fairly productive (brief) discussion on shared
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
Oct 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/Z8Yj2kwYTry __gshared Mutex mutex;
Oct 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:Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?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/Z8Yj2kwYTry __gshared Mutex mutex;
Oct 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:You can use auto mutex = cast(shared)(new Mutex());On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?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/Z8Yj2kwYTry __gshared Mutex mutex;
Oct 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:Globally you can use: Mutex mutex; static this() { mutex = new Mutex(); }On Sunday, 26 October 2014 at 22:14:25 UTC, Neven wrote:Thanks, that works now; but why? Why cannot I globally have auto mutex = new Mutex? And why it works now when I put __gshared?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/Z8Yj2kwYTry __gshared Mutex mutex;
Oct 26 2014
DamianYou 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 codeMutex 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. ketmarhaving thread-locals instead of globals by default can be confusing ifyou 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?
Oct 26 2014
On Sun, 26 Oct 2014 23:37:25 +0000 Neven via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote: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 =3D new Mutex(); } 'shared static this()' will be called only once.Mutex mutex; static this() { mutex =3D new Mutex(); }=20 I have synchronization problems with this one. Even when I=20 prepend __gshared Mutex mutex in this case.Thank you for clearing this up. If I understand correctly,=20 __gshared is more of a hack to get C-like global variables,=20 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. ;-)
Oct 26 2014
On Mon, 27 Oct 2014 02:07:09 +0200 ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote: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.Thank you for clearing this up. If I understand correctly,=20 __gshared is more of a hack to get C-like global variables,=20 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. =20 shared int a; pragma(msg, typeof(a)); // this will print "shared(int)" =20 __gshared int b; pragma(msg, typeof(b)); // this will print "int" =20 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. =20 '__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. =20 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. ;-)
Oct 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 =3D new Mutex? And why it=20 works now when I put __gshared?this is because 'auto mutex =3D 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.
Oct 26 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: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. -SteveWhy 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.
Oct 27 2014
On Mon, 27 Oct 2014 09:24:13 -0400 Steven Schveighoffer via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Just as a followup, for some reason Mutex is not callable as a shared=20 object, so you have to make it __gshared.that's due to difference betwen plain type and shared type. `shared(Mutex)` is not the same as simply `Mutex`. to use class as shared var you have to declare it as 'shared class'. or at least declare some of class methods as 'shared'. but for Mutex it's perfectly ok to use it as '__gshared' object.
Oct 27 2014
On Mon, 27 Oct 2014 09:24:13 -0400 Steven Schveighoffer via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Just as a followup, for some reason Mutex is not callable as a shared=20 object, so you have to make it __gshared. =20 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.p.s. generally you have to write code that can be used with shared vars with special accuracy. that's why D made a clear distinction between shared and thread variables and classes. you must explicitly declare your intention to use something as shared. generally this increases code safety and allows to writte better code. this can be somewhat unusual for those who used to use C/C++ before, as there is no such "guards" though.
Oct 27 2014
On 10/27/14 9:34 AM, ketmar via Digitalmars-d-learn wrote:On Mon, 27 Oct 2014 09:24:13 -0400 Steven Schveighoffer via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:But the result is that you can't use a mutex embedded in a shared object without casting (except for when it's the object's Monitor). Ironically, that's the one place you NEED a mutex. It's not a good situation.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.p.s. generally you have to write code that can be used with shared vars with special accuracy. that's why D made a clear distinction between shared and thread variables and classes. you must explicitly declare your intention to use something as shared. generally this increases code safety and allows to writte better code.this can be somewhat unusual for those who used to use C/C++ before, as there is no such "guards" though.The 'shared' system is really underdesigned in D, and needs complete overhaul. The opposite of it (default unshared) is an extremely useful mechanism. -Steve
Oct 27 2014
On Monday, October 27, 2014 09:24:13 Steven Schveighoffer via Digitalmars-d- learn wrote: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.The reason that it's not shared is because Sean Kelly didn't want to make much of anything in druntime shared until shared was better ironed out, which keeps getting talked about but never done. - Jonathan M Davis
Oct 27 2014
On Monday, 27 October 2014 at 19:13:13 UTC, Jonathan M Davis via Digitalmars-d-learn wrote:The reason that it's not shared is because Sean Kelly didn't want to make much of anything in druntime shared until shared was better ironed out, which keeps getting talked about but never done.Yep. There was a fairly productive (brief) discussion on shared in digitalmars.D recently, but no one who can really make such decisions weighed in. I honestly don't know when shared will get a serious look, despite it being probably the most significant unfinished language feature in D 2.0.
Oct 28 2014