| Thread overview | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 17, 2010 Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming. Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched. What do you think | ||||
December 17, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to wrzosk | On Friday 17 December 2010 13:47:05 wrzosk wrote:
> I believe that when new thread is being created, all static data is
> initialized inside new thread. What worries me is the fact, that many
> 'mini' threads will initialize all static data inside application. This
> may be somewhat time consuming.
> Maybe there should be a possibility to define 'Pure' thread that doesnt
> touch any static data, and in turn it could leave static constructors
> untouched.
>
> What do you think
That seems like it would be _really_ hard to do - probably impossible. The compiler would have to know which functions, types, and variables a thread accessed. I don't believe that compiler really knows anything about threads. It doesn't know which thread calls a particular function or accesses a particular variable. It knows about thread-local storage vs shared storage, and the type system restricts conversions between the two, but to do what you're suggesting, you'd have to have the compiler know which thread is calling which function and disallowing - at compile time - certain threads from calling certain functions. As it is, any thread can call anything and the compiler makes no attempt at tracking any of that. It just has restrictions with regards to thread-local and shared.
So, while it certainly seems like a good idea, I don't see how it would really be possible. It might be possible to make it so that a thread could be created which did not initialize any module or static variables (be they at class, struct, or function scope), but I don't see how the compiler could enforce that none of those variables were used. It would have to be up to the programmer to only call pure functions.
What _might_ be possible would be if you had a way of starting a thread which took a function (or overrode one) and that function _had_ to be strongly pure. Then it could skip running static constructors, because it would be impossible for any static variables to be accessed. However, the only way that you'd then get access to anything that thread did was from the return value of the function that started it, which not raises the issue of how you'd get the return value with the asynchronous nature of threads, but it would restrict the usage of such threads to the point that they'd be practically useless.
I think that you raise a valid concern, but I don't think that that's the way to handle it. Restricting static constructors and global or static variables in practice will help, and using immutable more will help. But if we want a means of making threads more lightweight, we probably need to look at a different way of doing it than you're suggesting.
This does make me wonder about static constructors and immutable though. It's currently possible to assign to both immutable and mutable module-scope variables in a static constructor. Such static constructors _must_ run for every thread or the thread-local portions are going to be wrong, but you _can't_ run them for immutable variables or you aren't sharing them between threads (or you're reassigning them each time that at new thread is created - I think that there's currently a bug on that). Perhaps static constructors which assign to immutable variables should have to be immutable, and mutable variables would have to be assigned in non-immutable static constructors. Then the immutable static constructors only get run once with the main thread, whereas the non- static ones get run for every thread.
- Jonathan M Davis
| |||
December 17, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sat, 18 Dec 2010 00:33:43 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > That seems like it would be _really_ hard to do - probably impossible. This is about TLS, right? If so, can't we just add a way to create a thread without TLS, so that any attempts to access it will cause an access violation? Sounds simple and useful enough. -- Best regards, Vladimir mailto:vladimir@thecybershadow.net | |||
December 17, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Friday 17 December 2010 15:17:14 Vladimir Panteleev wrote:
> On Sat, 18 Dec 2010 00:33:43 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
>
> wrote:
> > That seems like it would be _really_ hard to do - probably impossible.
>
> This is about TLS, right?
>
> If so, can't we just add a way to create a thread without TLS, so that any attempts to access it will cause an access violation? Sounds simple and useful enough.
Except that virtually _everything_ in D is in TLS. Only shared variables and some immutable variables aren't. So, unless you use a set of functions which uses shared variables for _everything_, that would be rather useless.
- Jonathan M Davis
| |||
December 17, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to wrzosk | wrzosk <dprogr@gmail.com> wrote: > I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming. > Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched. > > What do you think Unless you are spawning lots of threads and at arbitrary times, this is unlikely to be much of a problem. If it is, you likely should use a thread pool instead. Lastly, if you absolutely must, it is possible to spawn a thread using methods other than D's built-in thread-spawning functions, and those would not have their static constructors run. On the downside, you lose any guarantees the compiler could give you, as just about anything that is not a local variable is in TLS. -- Simen | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to wrzosk | On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said: > I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming. > Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched. > > What do you think You mean something like this: pure void doSomething(Tid parent) { int result = 1 + 1; parent.sendMessage(result); } void main() { spawn(&doSomething); ... wait for message ... } Perhaps 'spawn' could do this when you feed it with a pure function. -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | On Friday 17 December 2010 16:02:27 Michel Fortin wrote:
> On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said:
> > I believe that when new thread is being created, all static data is
> > initialized inside new thread. What worries me is the fact, that many
> > 'mini' threads will initialize all static data inside application. This
> > may be somewhat time consuming.
> > Maybe there should be a possibility to define 'Pure' thread that doesnt
> > touch any static data, and in turn it could leave static constructors
> > untouched.
> >
> > What do you think
>
> You mean something like this:
>
> pure void doSomething(Tid parent) {
> int result = 1 + 1;
> parent.sendMessage(result);
> }
>
> void main() {
> spawn(&doSomething);
> ... wait for message ...
> }
>
> Perhaps 'spawn' could do this when you feed it with a pure function.
That would only work if send() can be pure, and I really doubt that it can be. If it _can_, then that might be a good optimization, but I'm betting that it can't be done. Someone more familiar with how send() work would have to say on that though, since I'm not intimately familiar with how send() works.
- Jonathan M Davis
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2010-12-17 19:15:07 -0500, Jonathan M Davis <jmdavisProg@gmx.com> said: > On Friday 17 December 2010 16:02:27 Michel Fortin wrote: >> On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said: >>> I believe that when new thread is being created, all static data is >>> initialized inside new thread. What worries me is the fact, that many >>> 'mini' threads will initialize all static data inside application. This >>> may be somewhat time consuming. >>> Maybe there should be a possibility to define 'Pure' thread that doesnt >>> touch any static data, and in turn it could leave static constructors >>> untouched. >>> >>> What do you think >> >> You mean something like this: >> >> pure void doSomething(Tid parent) { >> int result = 1 + 1; >> parent.sendMessage(result); >> } >> >> void main() { >> spawn(&doSomething); >> ... wait for message ... >> } >> >> Perhaps 'spawn' could do this when you feed it with a pure function. > > That would only work if send() can be pure, and I really doubt that it can be. > If it _can_, then that might be a good optimization, but I'm betting that it > can't be done. Someone more familiar with how send() work would have to say on > that though, since I'm not intimately familiar with how send() works. That's an interesting question. There isn't much difference between sendMessage and appending a value to an array. A pure function can append things to a mutable array it gets as a parameter, so why couldn't it append to another thread's message queue it gets as a parameter? Your question is probably more about wether manipulating synchronization primitives should be pure or not. Things like locking a mutex or waiting on a condition. I don't see why they should not. Consider a strongly pure function that creates its own synchronization primitive for internal usage; how is that going to affect the rest of the program considering that no other parts of the program has access the same instances of those primitives? -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sat, 18 Dec 2010 01:27:01 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > Except that virtually _everything_ in D is in TLS. Only shared variables and > some immutable variables aren't. So, unless you use a set of functions which > uses shared variables for _everything_, that would be rather useless. But isn't that what OP's asking? Also, I wouldn't say it's useless... By _everything_ you mean global and class/function static variables, right? I can imagine lots of examples of using threads without having to access those variables. -- Best regards, Vladimir mailto:vladimir@thecybershadow.net | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Friday 17 December 2010 16:44:19 Vladimir Panteleev wrote:
> On Sat, 18 Dec 2010 01:27:01 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
>
> wrote:
> > Except that virtually _everything_ in D is in TLS. Only shared variables
> > and
> > some immutable variables aren't. So, unless you use a set of functions
> > which
> > uses shared variables for _everything_, that would be rather useless.
>
> But isn't that what OP's asking?
>
> Also, I wouldn't say it's useless... By _everything_ you mean global and class/function static variables, right? I can imagine lots of examples of using threads without having to access those variables.
And how about every other variable? If it's not shared or immutable, it's in TLS. Do you want to mark every single variable with shared? I believe that that's pretty much what you'd have to do. It's _rare_ in D that a variable is shared. You'd basically have to create a set of functions explictly intended to be used with such special threads.
- Jonathan M Davis
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply