digitalmars.D.learn - How to use globals correctly?
- =?iso-8859-1?Q?Robert_M._M=FCnch?= (29/29) Mar 05 2018 Hi, I'm feeling a bit dumb but anway...
- Steven Schveighoffer (13/22) Mar 05 2018 No, they are on the heap. Only the reference is __gshared. But
- Marc (6/29) Mar 05 2018 Can __gshared be used instead of static in the singleton pattern?
- Steven Schveighoffer (12/16) Mar 05 2018 static in D is thread safe, because it's thread-local. __gshared is
- bauss (5/23) Mar 06 2018 Singletons are always smelly code tbh.
- Jonathan M Davis (21/48) Mar 06 2018 I confess that I've never really understood why some folks dislike
- H. S. Teoh (13/26) Mar 06 2018 [...]
- =?iso-8859-1?Q?Robert_M._M=FCnch?= (10/27) Mar 05 2018 Ok, that was my idea. And am I right, that I don't need any special
- Steven Schveighoffer (14/35) Mar 05 2018 Yes. Like I said, __gshared means it's global, but it's not typed as
- bauss (7/11) Mar 05 2018 Because your code will become very verbose and you'll end up
- Jonathan M Davis (19/42) Mar 06 2018 Digitalmars-d-learn wrote:
Hi, I'm feeling a bit dumb but anway... For hacking prototypes I mostly create a class to store all kind of values. Then I create one global instance of this class and use it everywhere. Pseudocode looks like this: class myClass { myMemb1; myMembN; this(){...} } __gshared myClass myObj; main() { myObj = new myClass(); func1(); ... } func1(){ myObj.myMemb1 = ... } If I use VisualD and add a watch on myObj, I don't see anything just a "identifier myObj is undefined". Not sure if this is because of some threads running (using the D RX framework). So, some questions: 1. Are myMemb1..N TLS or __gshared as well? 2. How to best implement a simple global to keep track of values (with support for threads)? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Mar 05 2018
On 3/5/18 1:35 PM, Robert M. Münch wrote:If I use VisualD and add a watch on myObj, I don't see anything just a "identifier myObj is undefined". Not sure if this is because of some threads running (using the D RX framework).Can't answer your visual D questions...So, some questions: 1. Are myMemb1..N TLS or __gshared as well?No, they are on the heap. Only the reference is __gshared. But effectively it is __gshared, since you can reach those items via the global `myObj`.2. How to best implement a simple global to keep track of values (with support for threads)?shared is the best mechanism, and you don't have to make it a class, it can be a struct. This is only if you are using it as POD (plain old data). If you want to have methods, shared kind of sucks. But this at least tells the type system that it's shared between threads. __gshared does not, it just sticks it in global space, but pretends it's not shared data. -Steve
Mar 05 2018
On Monday, 5 March 2018 at 18:57:01 UTC, Steven Schveighoffer wrote:On 3/5/18 1:35 PM, Robert M. Münch wrote:Can __gshared be used instead of static in the singleton pattern? I, comming from C++, ignorantly, have never used _gshared so I went to static instead of (being static also means thread-safe, as far I know)...If I use VisualD and add a watch on myObj, I don't see anything just a "identifier myObj is undefined". Not sure if this is because of some threads running (using the D RX framework).Can't answer your visual D questions...So, some questions: 1. Are myMemb1..N TLS or __gshared as well?No, they are on the heap. Only the reference is __gshared. But effectively it is __gshared, since you can reach those items via the global `myObj`.2. How to best implement a simple global to keep track of values (with support for threads)?shared is the best mechanism, and you don't have to make it a class, it can be a struct. This is only if you are using it as POD (plain old data). If you want to have methods, shared kind of sucks. But this at least tells the type system that it's shared between threads. __gshared does not, it just sticks it in global space, but pretends it's not shared data. -Steve
Mar 05 2018
On 3/5/18 2:25 PM, Marc wrote:Can __gshared be used instead of static in the singleton pattern? I, comming from C++, ignorantly, have never used _gshared so I went to static instead of (being static also means thread-safe, as far I know)...static in D is thread safe, because it's thread-local. __gshared is shared between threads, so it's not thread safe, but has the exact same type as just static data. Can you use it for singleton? Sure, classic singleton is shared between threads. But using thread-local data, you can solve the singleton problem in a better way: https://wiki.dlang.org/Low-Lock_Singleton_Pattern Note, it still uses __gshared, which means it doesn't protect you from race conditions when you actually USE the singleton object. This means you need some synchronization inside the methods. -Steve
Mar 05 2018
On Monday, 5 March 2018 at 19:51:33 UTC, Steven Schveighoffer wrote:On 3/5/18 2:25 PM, Marc wrote:Singletons are always smelly code tbh. Especially in D with thread-local storage. I can't think of a situation where you truly need singletons in D.Can __gshared be used instead of static in the singleton pattern? I, comming from C++, ignorantly, have never used _gshared so I went to static instead of (being static also means thread-safe, as far I know)...static in D is thread safe, because it's thread-local. __gshared is shared between threads, so it's not thread safe, but has the exact same type as just static data. Can you use it for singleton? Sure, classic singleton is shared between threads. But using thread-local data, you can solve the singleton problem in a better way: https://wiki.dlang.org/Low-Lock_Singleton_Pattern Note, it still uses __gshared, which means it doesn't protect you from race conditions when you actually USE the singleton object. This means you need some synchronization inside the methods. -Steve
Mar 06 2018
On Tuesday, March 06, 2018 18:34:34 bauss via Digitalmars-d-learn wrote:On Monday, 5 March 2018 at 19:51:33 UTC, Steven Schveighoffer wrote:I confess that I've never really understood why some folks dislike singletons so much, but then again, I've only rarely found cases where I thought that they made sense, and I gather that some folks out there use the singleton pattern way too much (I've heard it suggested that it's because it was one of the few design patterns from the design pattern book that was easy). In fact, one of my coworkers was telling me at one point about how someone had argued to him about how a "doubleton" pattern made sense, which just seems crazy to me, but I've found that a disturbingly large percentage of programmers are not what I would consider competent. I think that the singleton pattern should be used when it really makes sense to use it, but in most cases, there's no reason to restrict the type to a singleton. And I expect that the dislike for singletons comes from them being used far too often when it clearly made no sense. The one place that I can think of that I've used singletons in the last decade or so is with the LocalTime and UTC classes for time zones (both in std.datetime and in the C++ version that I wrote for work at one point). Having multiple instances of those classes made no sense and would have been pointlessly inefficient. But at the moment, that's the only case I can think of where I've used singletons. They just don't make sense very often. - Jonathan M DavisOn 3/5/18 2:25 PM, Marc wrote:Singletons are always smelly code tbh. Especially in D with thread-local storage. I can't think of a situation where you truly need singletons in D.Can __gshared be used instead of static in the singleton pattern? I, comming from C++, ignorantly, have never used _gshared so I went to static instead of (being static also means thread-safe, as far I know)...static in D is thread safe, because it's thread-local. __gshared is shared between threads, so it's not thread safe, but has the exact same type as just static data. Can you use it for singleton? Sure, classic singleton is shared between threads. But using thread-local data, you can solve the singleton problem in a better way: https://wiki.dlang.org/Low-Lock_Singleton_Pattern Note, it still uses __gshared, which means it doesn't protect you from race conditions when you actually USE the singleton object. This means you need some synchronization inside the methods. -Steve
Mar 06 2018
On Tue, Mar 06, 2018 at 11:46:04AM -0700, Jonathan M Davis via Digitalmars-d-learn wrote:On Tuesday, March 06, 2018 18:34:34 bauss via Digitalmars-d-learn wrote:[...][...] To me, a singleton is a symptom of excessive dogmatic adherence to the OO religion where Everything Must Be A Class No Matter What. When there can only be one of something, it's clearly no longer a *class*, but is either a module, a global variable, or a (set of) global function(s). I'm curious to know what are the few cases where you think a singleton made sense, where it wouldn't be more appropriately implemented as a module, global variable, or global function(s). T -- Старый друг лучше новых двух.Singletons are always smelly code tbh. Especially in D with thread-local storage. I can't think of a situation where you truly need singletons in D.I confess that I've never really understood why some folks dislike singletons so much, but then again, I've only rarely found cases where I thought that they made sense, and I gather that some folks out there use the singleton pattern way too much (I've heard it suggested that it's because it was one of the few design patterns from the design pattern book that was easy).
Mar 06 2018
On 2018-03-05 18:57:01 +0000, Steven Schveighoffer said:On 3/5/18 1:35 PM, Robert M. Münch wrote:Ok, that was my idea. And am I right, that I don't need any special syntax, just: myObj.myMemb1. Are myMemb1..N TLS or __gshared as well?No, they are on the heap. Only the reference is __gshared. But effectively it is __gshared, since you can reach those items via the global `myObj`.Ok, in my case I have some methods as well (but maybe can be avoided).2. How to best implement a simple global to keep track of values (with support for threads)?Shared is the best mechanism, and you don't have to make it a class, it can be a struct. This is only if you are using it as POD (plain old data).If you want to have methods, shared kind of sucks. But this at least tells the type system that it's shared between threads.Why does it suck?__gshared does not, it just sticks it in global space, but pretends it's not shared data.Ok, so this is the really hackish solution... -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Mar 05 2018
On 3/5/18 2:39 PM, Robert M. Münch wrote:On 2018-03-05 18:57:01 +0000, Steven Schveighoffer said:Yes. Like I said, __gshared means it's global, but it's not typed as shared. So the compiler will let you do anything you want.On 3/5/18 1:35 PM, Robert M. Münch wrote:Ok, that was my idea. And am I right, that I don't need any special syntax, just: myObj.myMemb1. Are myMemb1..N TLS or __gshared as well?No, they are on the heap. Only the reference is __gshared. But effectively it is __gshared, since you can reach those items via the global `myObj`.Because you can't call shared methods on a non-shared object, and vice versa. Once you start putting more complex data types inside a class/struct that is shared, you start not being able to use them. If you're just storing strings and integers, it's probably ok.If you want to have methods, shared kind of sucks. But this at least tells the type system that it's shared between threads.Why does it suck?__gshared is for those who "know what they are doing". There is more exposure to race conditions, and there is a LOT of code that assumes if something isn't typed as shared, it's not shared. __gshared is kind of a lie in that case, and you can potentially run into problems. If you're doing simple things, it can possibly be OK, especially if it's just for debugging. -Steve__gshared does not, it just sticks it in global space, but pretends it's not shared data.Ok, so this is the really hackish solution...
Mar 05 2018
On Monday, 5 March 2018 at 19:39:35 UTC, Robert M. Münch wrote:On 2018-03-05 18:57:01 +0000, Steven Schveighoffer said:Because your code will become very verbose and you'll end up casting shared away to do stuff. Basically you won't be able to do anything that isn't in a synchronized context and such your code will either have synchronized everywhere or you'll cast away shared. Personally I never use shared, because it's just such a bother.If you want to have methods, shared kind of sucks. But this at least tells the type system that it's shared between threads.Why does it suck?
Mar 05 2018
On Tuesday, March 06, 2018 11:52:05 H. S. Teoh via Digitalmars-d-learn wrote:On Tue, Mar 06, 2018 at 11:46:04AM -0700, Jonathan M Davis viaDigitalmars-d-learn wrote:It makes sense whenever it doesn't make sense to have multiple instances of a particular class, and it makes sense to enforce that. As I explained, LocalTime and UTC from std.datetime do that for exactly that reason. Cases like that are rare, but they do exist. However, they also exist rarely enough that it's going to be hard to come up with more examples. I judge whether singletons makes sense on a case-by-case basis. Sometimes, they do make sense, so I wouldn't say that they're necessarily a code smell, but I also completely agree that they rarely make sense. So, I don't disagree that singletons should rarely be used. I just disagree with the idea that they should never be used. And for better or worse, singletons are one of those things that seems to me like it should usually be obvious whether they make sense in a particular case, but that doesn't seem to be true for everyone, otherwise there wouldn't be as much of a dislike of singletons as there seems to be, since they wouldn't come up very often. - Jonathan M DavisOn Tuesday, March 06, 2018 18:34:34 bauss via Digitalmars-d-learn wrote:[...][...] To me, a singleton is a symptom of excessive dogmatic adherence to the OO religion where Everything Must Be A Class No Matter What. When there can only be one of something, it's clearly no longer a *class*, but is either a module, a global variable, or a (set of) global function(s). I'm curious to know what are the few cases where you think a singleton made sense, where it wouldn't be more appropriately implemented as a module, global variable, or global function(s).Singletons are always smelly code tbh. Especially in D with thread-local storage. I can't think of a situation where you truly need singletons in D.I confess that I've never really understood why some folks dislike singletons so much, but then again, I've only rarely found cases where I thought that they made sense, and I gather that some folks out there use the singleton pattern way too much (I've heard it suggested that it's because it was one of the few design patterns from the design pattern book that was easy).
Mar 06 2018