www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Threads and Static Data

reply "Craig Black" <craigblack2 cox.net> writes:
I'm in the process of hashing out a design for multi-core support for a 
large API developed by myself and a couple other people.  I realized that 
static data can be problematic for multiple threads.  In many cases, it 
seems that static data should be instantiated on a per-thread basis.  My 
solution to this problem is to use a template class called "Threaded" that 
instantiates data for each thread.

static Threaded!(int) x;

Then to access the value, there would have to be a thread ID passed into it. 
So to increment the value you would have.

int temp = x.get(threadID);
x.set(threadID, temp+1);

(Or, I guess you could use a pointer.)

int *ptr = x.getptr(threadID);
(*ptr)++;

This solution will do the job, but it is a little clumsy.  This seems like 
this is a common problem that warrants better syntax.  Ideally, I would like 
to be able access a "threaded" variable just like any other so that the 
above example is simply "x++".  I don't have extensive experience with D 
templates and operator overloading.  It it possible to make this work 
transparently with all operators?  I want to support all basic types as well 
as structs and classes.  Could someone with more experience fill me in on 
the caveats involved in implementing something like this?  Has anyone else 
already solved this problem?  This seems like a feature that should be 
included in the standard library.

-Craig 
Dec 09 2007
next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Craig Black wrote:
 I'm in the process of hashing out a design for multi-core support for a 
 large API developed by myself and a couple other people.  I realized 
 that static data can be problematic for multiple threads.  In many 
 cases, it seems that static data should be instantiated on a per-thread 
 basis.  My solution to this problem is to use a template class called 
 "Threaded" that instantiates data for each thread.
 
 static Threaded!(int) x;
 
 Then to access the value, there would have to be a thread ID passed into 
 it. So to increment the value you would have.
 
 int temp = x.get(threadID);
 x.set(threadID, temp+1);
 
 (Or, I guess you could use a pointer.)
 
 int *ptr = x.getptr(threadID);
 (*ptr)++;
 
 This solution will do the job, but it is a little clumsy.  This seems 
 like this is a common problem that warrants better syntax.  Ideally, I 
 would like to be able access a "threaded" variable just like any other 
 so that the above example is simply "x++".  I don't have extensive 
 experience with D templates and operator overloading.  It it possible to 
 make this work transparently with all operators?  I want to support all 
 basic types as well as structs and classes.  Could someone with more 
 experience fill me in on the caveats involved in implementing something 
 like this?  Has anyone else already solved this problem?  This seems 
 like a feature that should be included in the standard library.
 
 -Craig

Tango has tango.core.Thread.ThreadLocal for thrad-local storage. I don't know about phobos, but if it's not there it should be.
Dec 09 2007
parent reply "Craig Black" <cblack ara.com> writes:
"Robert Fraser" <fraserofthenight gmail.com> wrote in message 
news:fjip5u$2uud$1 digitalmars.com...
 Craig Black wrote:
 I'm in the process of hashing out a design for multi-core support for a 
 large API developed by myself and a couple other people.  I realized that 
 static data can be problematic for multiple threads.  In many cases, it 
 seems that static data should be instantiated on a per-thread basis.  My 
 solution to this problem is to use a template class called "Threaded" 
 that instantiates data for each thread.

 static Threaded!(int) x;

 Then to access the value, there would have to be a thread ID passed into 
 it. So to increment the value you would have.

 int temp = x.get(threadID);
 x.set(threadID, temp+1);

 (Or, I guess you could use a pointer.)

 int *ptr = x.getptr(threadID);
 (*ptr)++;

 This solution will do the job, but it is a little clumsy.  This seems 
 like this is a common problem that warrants better syntax.  Ideally, I 
 would like to be able access a "threaded" variable just like any other so 
 that the above example is simply "x++".  I don't have extensive 
 experience with D templates and operator overloading.  It it possible to 
 make this work transparently with all operators?  I want to support all 
 basic types as well as structs and classes.  Could someone with more 
 experience fill me in on the caveats involved in implementing something 
 like this?  Has anyone else already solved this problem?  This seems like 
 a feature that should be included in the standard library.

 -Craig

Tango has tango.core.Thread.ThreadLocal for thrad-local storage. I don't know about phobos, but if it's not there it should be.

Suite! I think I've seen the term "thread local", but it never occured to me what it meant. Goes to show you how green I am when it comes to threading. I'll check it out. Thanks. -Craig
Dec 10 2007
parent reply Sean Kelly <sean f4.ca> writes:
Craig Black wrote:
 
 Suite!  I think I've seen the term "thread local", but it never occured to 
 me what it meant.  Goes to show you how green I am when it comes to 
 threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time. Sean
Dec 10 2007
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when it 
 comes to threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

If I want thread local storage I just add the variables as static members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R
Dec 10 2007
next sibling parent reply Sean Kelly <sean f4.ca> writes:
Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when it 
 comes to threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

If I want thread local storage I just add the variables as static members of the class I've derived from Thread.

Yup. static ThreadLocal!(T) myVar;
 Does thread local storage give us some advantage over that?

If I understand you correctly, ThreadLocal(T) is simply a front-end for the Thread.get/setLocal routines. It provides type safety and convenience but stores the data in a dynamically allocated object, and the one allocation per thread may or may not be something you want to pay for. This is why both methods are available. Sean
Dec 10 2007
parent Sean Kelly <sean f4.ca> writes:
Sean Kelly wrote:
 Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

If I want thread local storage I just add the variables as static members of the class I've derived from Thread.

Yup. static ThreadLocal!(T) myVar;

Oops, I misunderstood the question. There's one big problems with this approach: the object representing the main application thread cannot be modified. Sean
Dec 10 2007
prev sibling next sibling parent reply "Craig Black" <cblack ara.com> writes:
"Regan Heath" <regan netmail.co.nz> wrote in message 
news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never occured 
 to me what it meant.  Goes to show you how green I am when it comes to 
 threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

If I want thread local storage I just add the variables as static members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.
Dec 10 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never occured 
 to me what it meant.  Goes to show you how green I am when it comes to 
 threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.

Why not? The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class. Regan
Dec 11 2007
parent reply Sean Kelly <sean f4.ca> writes:
Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.

Why not? The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

A library designer doesn't always have the ability to dictate what goes in a thread class, or necessarily even knows whether the library will be used in a multithreaded program. Sean
Dec 11 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.

Why not? The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

A library designer doesn't always have the ability to dictate what goes in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

That's true, if the library uses global variables. Otherwise you can stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something. Regan
Dec 11 2007
next sibling parent Sean Kelly <sean f4.ca> writes:
Regan Heath wrote:
 Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am 
 when it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.

Why not? The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

A library designer doesn't always have the ability to dictate what goes in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

That's true, if the library uses global variables. Otherwise you can stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something.

That's pretty much it. Sometimes implementation-level static data isn't used in a way that makes it easy to embed in a user-level handle. Or it may be that user-level granularity is just plain wrong. Some cached data, for example, may be best applied as common to all users, but protecting it via a mutex could cause entirely different problems. Sean
Dec 11 2007
prev sibling parent reply "Craig Black" <cblack ara.com> writes:
"Regan Heath" <regan netmail.co.nz> wrote in message 
news:fjmigm$vhf$1 digitalmars.com...
 Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

Storing all your static data for everything in a thread class is not ideal from a software design perspective IMO.

Why not? The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

A library designer doesn't always have the ability to dictate what goes in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

That's true, if the library uses global variables. Otherwise you can stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something. Regan

Think of multiple plug-in librariess to an application. The application is responsible for creating the threads. In order for the plug-ins to add their respective thread local data to the thread class, they have to inherit it. So now plug-in A has class ThreadA and plugin B has class ThreadB. Which class should the application instantiate to start a thread? -Craig
Dec 12 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjmigm$vhf$1 digitalmars.com...
 Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

ideal from a software design perspective IMO.

The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something. Regan

Think of multiple plug-in librariess to an application. The application is responsible for creating the threads. In order for the plug-ins to add their respective thread local data to the thread class, they have to inherit it. So now plug-in A has class ThreadA and plugin B has class ThreadB. Which class should the application instantiate to start a thread?

Well, I was assuming the plug in library had some class or struct and some methods or functions to call on those objects... but you're suggesting the plug in publishes a thread class? That's a bit weird, but ok. I would create a ThreadC (derived from the Thread base) class and have a reference to both ThreadA and ThreadB in it. I then instantiate ThreadC for each thread I need, where the constructor for ThreadC instantiates but does not 'start' ThreadA or ThreadB. So, each and every ThreadC object contains a copy of the data that ThreadA and ThreadB contain, or rather a copy of the data the plug in requires. Regan
Dec 13 2007
parent reply "Craig Black" <cblack ara.com> writes:
"Regan Heath" <regan netmail.co.nz> wrote in message 
news:fjqu5t$2dvs$1 digitalmars.com...
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjmigm$vhf$1 digitalmars.com...
 Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

ideal from a software design perspective IMO.

The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something. Regan

Think of multiple plug-in librariess to an application. The application is responsible for creating the threads. In order for the plug-ins to add their respective thread local data to the thread class, they have to inherit it. So now plug-in A has class ThreadA and plugin B has class ThreadB. Which class should the application instantiate to start a thread?

Well, I was assuming the plug in library had some class or struct and some methods or functions to call on those objects... but you're suggesting the plug in publishes a thread class? That's a bit weird, but ok. I would create a ThreadC (derived from the Thread base) class and have a reference to both ThreadA and ThreadB in it. I then instantiate ThreadC for each thread I need, where the constructor for ThreadC instantiates but does not 'start' ThreadA or ThreadB. So, each and every ThreadC object contains a copy of the data that ThreadA and ThreadB contain, or rather a copy of the data the plug in requires. Regan

What you suggest will not work if plug-in A was created by company A and plug-in B was created by company B. They know nothing about each other and do not release source code. Inheritance is not a good solution here. A system that would work is one where the base thread class has a static container of object factories. Then each plug-in could submit their object factory to the base thread class. Then, object factory A could instantiate class A to support plug-in A, and object factory B could instantiate class B to support plug-in B, etc. The object factories would be called whenever a thread is instantiated. Most likely, the ThreadLocal template in Tango probably uses a system similar to this. I'm not sure about the details though. -Craig
Dec 13 2007
parent Sean Kelly <sean f4.ca> writes:
Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjqu5t$2dvs$1 digitalmars.com...
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjmigm$vhf$1 digitalmars.com...
 Sean Kelly wrote:
 Regan Heath wrote:
 Craig Black wrote:
 "Regan Heath" <regan netmail.co.nz> wrote in message 
 news:fjjtr4$6g2$1 digitalmars.com...
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never 
 occured to me what it meant.  Goes to show you how green I am when 
 it comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that? R

ideal from a software design perspective IMO.

The way I see it members of a thread class are essentially the same thing as global variables in a program. The program is just the first thread, and it's member variables are global variables. The difference is that any thread you create has public access to the program/main threads member/global variables, which is actually worse in terms of encapsulation than using thread classes and member variables. So, I reckon if you want "a variable which is private to a thread" why not just make it a member of your thread class.

in a thread class, or necessarily even knows whether the library will be used in a multithreaded program.

stick the libraries data structures/classes/etc into the thread as members. Right? Or am I missing something. Regan

is responsible for creating the threads. In order for the plug-ins to add their respective thread local data to the thread class, they have to inherit it. So now plug-in A has class ThreadA and plugin B has class ThreadB. Which class should the application instantiate to start a thread?

methods or functions to call on those objects... but you're suggesting the plug in publishes a thread class? That's a bit weird, but ok. I would create a ThreadC (derived from the Thread base) class and have a reference to both ThreadA and ThreadB in it. I then instantiate ThreadC for each thread I need, where the constructor for ThreadC instantiates but does not 'start' ThreadA or ThreadB. So, each and every ThreadC object contains a copy of the data that ThreadA and ThreadB contain, or rather a copy of the data the plug in requires. Regan

What you suggest will not work if plug-in A was created by company A and plug-in B was created by company B. They know nothing about each other and do not release source code. Inheritance is not a good solution here. A system that would work is one where the base thread class has a static container of object factories. Then each plug-in could submit their object factory to the base thread class. Then, object factory A could instantiate class A to support plug-in A, and object factory B could instantiate class B to support plug-in B, etc. The object factories would be called whenever a thread is instantiated. Most likely, the ThreadLocal template in Tango probably uses a system similar to this. I'm not sure about the details though.

It's a bit simpler than this right now. It would be easy enough to let the user provide delegates to auto-construct data on thread initialization, but given that these could throw, I'm hesitant to do so. Sean
Dec 13 2007
prev sibling parent reply =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never
 occured to me what it meant.  Goes to show you how green I am when it
 comes to threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

If I want thread local storage I just add the variables as static members of the class I've derived from Thread. Does thread local storage give us some advantage over that?

same time, your variables won't be local, will they? Jerome - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFHXYrXd0kWM4JG3k8RArl2AJ47m7+I351Uzsq5d5IPztpmOeNNXACdEaSf WLPKfctUHx5gvl3b6nFMxSk= =06vK -----END PGP SIGNATURE-----
Dec 10 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Jérôme M. Berger wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never
 occured to me what it meant.  Goes to show you how green I am when it
 comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that?

same time, your variables won't be local, will they?

What do you mean by "local"? If you want a copy of the variables for each thread, make them non-static members of the thread. Regan
Dec 11 2007
parent reply =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Regan Heath wrote:
 Jérôme M. Berger wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never
 occured to me what it meant.  Goes to show you how green I am when it
 comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that?

same time, your variables won't be local, will they?

What do you mean by "local"? If you want a copy of the variables for each thread,

That's what is usually meant by "thread local", yes.
 make them non-static members of the thread.
 

of your environment. In particular, if you are writing a library and don't know if that library will be used in a single-threaded or multi-threaded environment, then you cannot put any data in the thread class since you won't have access to it in the first place. OTOH, properly designed libraries should store all their data for a given task in a struct (or class) and let the caller manage that struct however he wants (local variable, class member, global variable, whatever). So thread local storage isn't that useful. Jerome - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFHXtuTd0kWM4JG3k8RAscyAKCqAJP8MVnF6Qzbukril7bMgH8sYgCePrCC gbNfsqvWLQdNpOaTVm1liOs= =DurB -----END PGP SIGNATURE-----
Dec 11 2007
parent reply "Craig Black" <cblack ara.com> writes:
""Jérôme M. Berger"" <jeberger free.fr> wrote in message 
news:fjmm2j$18pc$1 digitalmars.com...
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Regan Heath wrote:
 Jérôme M. Berger wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never
 occured to me what it meant.  Goes to show you how green I am when it
 comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that?

same time, your variables won't be local, will they?

What do you mean by "local"? If you want a copy of the variables for each thread,

That's what is usually meant by "thread local", yes.
 make them non-static members of the thread.

of your environment. In particular, if you are writing a library and don't know if that library will be used in a single-threaded or multi-threaded environment, then you cannot put any data in the thread class since you won't have access to it in the first place. OTOH, properly designed libraries should store all their data for a given task in a struct (or class) and let the caller manage that struct however he wants (local variable, class member, global variable, whatever). So thread local storage isn't that useful.

I'm not following you. Is what you are suggesting just another way to do thread local storage using a data structure that is instantiated each time a thread is instantiated? Isn't this the exact same thing as the ThreadLocal template provided in Tango? The bottom line is that data has to be instantiated with each thread. I don't see a way around this.
Dec 12 2007
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Craig Black wrote:
 ""Jerome M. Berger"" <jeberger free.fr> wrote in message 
 news:fjmm2j$18pc$1 digitalmars.com...
 Regan Heath wrote:
 Jerome M. Berger wrote:
 Regan Heath wrote:
 Sean Kelly wrote:
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never
 occured to me what it meant.  Goes to show you how green I am when it
 comes to threading.  I'll check it out.  Thanks.

storage class. I've proposed adding this to D before, but there seemed to be no interest at the time.

members of the class I've derived from Thread. Does thread local storage give us some advantage over that?

same time, your variables won't be local, will they?

If you want a copy of the variables for each thread,

 make them non-static members of the thread.

of your environment. In particular, if you are writing a library and don't know if that library will be used in a single-threaded or multi-threaded environment, then you cannot put any data in the thread class since you won't have access to it in the first place. OTOH, properly designed libraries should store all their data for a given task in a struct (or class) and let the caller manage that struct however he wants (local variable, class member, global variable, whatever). So thread local storage isn't that useful.

I'm not following you. Is what you are suggesting just another way to do thread local storage using a data structure that is instantiated each time a thread is instantiated? Isn't this the exact same thing as the ThreadLocal template provided in Tango? The bottom line is that data has to be instantiated with each thread. I don't see a way around this.

- Tango does not work on my platform (Linux 64 bits + gdc) so I'm not 100% sure of what exactly ThreadLocal does (although I can guess); - There were two very different points in my message and I'm not sure which one you're answering to. That being said, I'll try to clarify what I meant: - My first point was to illustrate what thread-local storage is for as opposed to instance variables in the thread class. Another illustration would be to point to this Wikipedia page: http://en.wikipedia.org/wiki/Thread-local_storage - My second point was that a specific thread-local storage mechanism isn't really needed if the libraries are properly designed. Properly designed libraries should have an "Init" or "Open" function that returns a handle, then all other functions should take that handle as a parameter(*). For such libraries, local variables are enough and a mechanism such as described in the Wikipedia page is overkill. Therefore, I don't think it's really necessary to add it to the core language: having it implemented in a library is enough for the rare cases where it's impossible to do without. Jerome (*) This can of course be done by returning some object instance and calling methods of this object instead of passing a handle around explicitly. - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFHYDmBd0kWM4JG3k8RAuxMAJ9nLLkXgW4LtBLqFpua9lh6ssAsNgCgu8jh CKBNGhNHyatM1TwwhDFc7PU= =T5qA -----END PGP SIGNATURE-----
Dec 12 2007
next sibling parent "Craig Black" <cblack ara.com> writes:
 - My second point was that a specific thread-local storage
 mechanism isn't really needed if the libraries are properly
 designed. Properly designed libraries should have an "Init" or
 "Open" function that returns a handle, then all other functions
 should take that handle as a parameter(*). For such libraries, local
 variables are enough and a mechanism such as described in the
 Wikipedia page is overkill. Therefore, I don't think it's really
 necessary to add it to the core language: having it implemented in a
 library is enough for the rare cases where it's impossible to do
 without.

Ok, you are saying it's not necessary to make it part of the language. You are right, this can be done pretty well without language support. It just requires a little more thought. This solution is still called thread-local storage I think even if it's not a language feature.
Dec 12 2007
prev sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Jérôme M. Berger wrote:
  - My first point was to illustrate what thread-local storage is for
 as opposed to instance variables in the thread class. Another
 illustration would be to point to this Wikipedia page:
 http://en.wikipedia.org/wiki/Thread-local_storage

I think the short explaination is that thread local storage is required when you want a separate copy of any _global_ variable for each thread. If you have no global varaibles, you don't need it. 'errno' described in the wikipedia page is the classic example. It is a global variable that many unrelated[1] ANSI C functions will set on error. If it was not global how would these functions access it in order to set it. If it was not global how would you know where it was in order to check it. errno and those ANSI functions are like static members of an "ANSI" class which is instantiated when your program runs. Imagine now what would happen if they were non static members of that class. Instead of having only one copy of errno you would have one per instance of "ANSI", meaning you could instantiate a different one for each thread you started. Problem solved, not need for thread local storage or any other mechanism for ensuring separate copies of global variables per thread. The same logic can be applied to any other library you care to name, if it has an errno style variable then _it_ will need to use thread local storage, if it doesn't it's not thread safe[3], period. On the other hand if the library encapsulates all it's variables in a class or struct[2] then you are free to have a separate instance of the class or struct per thread, typically as a member of your thread class. Regan [1]unrelated in that they perform many and varied tasks, related in that they are all ANSI C functions and they all use errno. [2]unless they are static members of a class, as this gives only one copy per process and again thread local storage has to be used, or it will never be thread safe[3]. [3]unless the variable is protected by synchronisation constructs like critical sections or mutexes.
Dec 13 2007
next sibling parent Sean Kelly <sean f4.ca> writes:
Regan Heath wrote:
 
 On the other hand if the library encapsulates all it's variables in a 
 class or struct[2] then you are free to have a separate instance of the 
 class or struct per thread, typically as a member of your thread class.

The only catch being that you would either have to pass that variable into all relevant calls in the library, or the library would have to maintain a thread-local reference to it. Sean
Dec 13 2007
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Regan Heath wrote:
 Jérôme M. Berger wrote:
  - My first point was to illustrate what thread-local storage is for
 as opposed to instance variables in the thread class. Another
 illustration would be to point to this Wikipedia page:
 http://en.wikipedia.org/wiki/Thread-local_storage

I think the short explaination is that thread local storage is required when you want a separate copy of any _global_ variable for each thread. If you have no global varaibles, you don't need it.

 ...
 On the other hand if the library encapsulates all it's variables in a
 class or struct[2] then you are free to have a separate instance of the
 class or struct per thread, typically as a member of your thread class.
 

Jerome - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFHYYeLd0kWM4JG3k8RAjmZAJ9TrkrQWsY8pLFiiL7QaAlP4Jaw2wCfeMvm bFU0D7dHNx6igQpKAy4gNxY= =3KGC -----END PGP SIGNATURE-----
Dec 13 2007
prev sibling parent "Craig Black" <cblack ara.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message 
news:fjjp7l$2t9c$2 digitalmars.com...
 Craig Black wrote:
 Suite!  I think I've seen the term "thread local", but it never occured 
 to me what it meant.  Goes to show you how green I am when it comes to 
 threading.  I'll check it out.  Thanks.

For what it's worth, some C/C++ compilers have "thread local" as a storage class. I've proposed adding this to D before, but there seemed to be no interest at the time. Sean

It would definitely be convenient.
Dec 10 2007
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Craig Black wrote:
 
 This solution will do the job, but it is a little clumsy.  This seems 
 like this is a common problem that warrants better syntax.  Ideally, I 
 would like to be able access a "threaded" variable just like any other 
 so that the above example is simply "x++".

See tango.core.Thread: Thread.get/setLocal or ThreadLocal(T). Sean
Dec 10 2007
parent Frank Benoit <keinfarbton googlemail.com> writes:
Sean Kelly schrieb:
 Craig Black wrote:
 This solution will do the job, but it is a little clumsy.  This seems
 like this is a common problem that warrants better syntax.  Ideally, I
 would like to be able access a "threaded" variable just like any other
 so that the above example is simply "x++".

See tango.core.Thread: Thread.get/setLocal or ThreadLocal(T). Sean

See also http://dsource.org/projects/tango/wiki/ChapterThreading#ThreadLocalStorageTLS
Dec 10 2007