Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 29, 2005 custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Generally I'm looking for a 'nice' and portable way to be able to associate some arbitrary data with a particular thread. And, what's not less important to have a hook to be called when a thread ceases to exist, to throw it's associated information to the GC ! For example, I have a program with lots of string work... I thought of allocating a per-thread more-or-less persistant stringbuffer to minimize memory [de-]allocation. To be general there were many situations when I had headaches how to keep track of some THINGS commonly used throughout lots of different code. I thought of some options outlined below, but none of them seemes satisfactory to me. - move them along as function parameters or class members, (which I actually hated, for I hate redundancy) - make them global, leading to a less flexible solution (which I hate even more :-) - have a global pool of reusable items and lots of mutex stuff to make everything thread safe (I don't like this too, because it smells like a bottleneck) I thought, If there were a mechanism, clean, portable and efficient, to work with per-thread data, this were a nice option in SOME situations. Can someone suggest anything? |
April 29, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to B.G. | What about this? class MyTread: Tread { //.... your per-thread data.... override void run() { // ...usefull thread code... } } Am I missing something? Andrew. "B.G." <B.G._member@pathlink.com> wrote in message news:d4tapi$p0n$1@digitaldaemon.com... > > Generally I'm looking for a 'nice' and portable way to be able to > associate some > arbitrary data with a particular thread. And, what's not less important to > have > a hook to be called when a thread ceases to exist, to throw it's > associated > information to the GC ! > > For example, I have a program with lots of string work... I thought of allocating a per-thread more-or-less persistant stringbuffer to minimize memory [de-]allocation. > > To be general there were many situations when I had headaches how to keep > track > of some THINGS commonly used throughout lots of different code. > I thought of some options outlined below, but none of them seemes > satisfactory > to me. > > - move them along as function parameters or class members, (which I > actually > hated, for I hate redundancy) > - make them global, leading to a less flexible solution > (which I hate even more :-) > - have a global pool of reusable items and lots of mutex stuff to > make everything thread safe > (I don't like this too, because it smells like a bottleneck) > > I thought, If there were a mechanism, clean, portable and efficient, to > work > with per-thread data, this were a nice option in SOME situations. > > Can someone suggest anything? > > |
April 30, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | Doesn't help you much if you want to write a thread-agnostic library. "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d4tm9a$14pq$1@digitaldaemon.com... > What about this? > > class MyTread: Tread > { > //.... your per-thread data.... > override void run() > { > // ...usefull thread code... > } > } > > Am I missing something? > > Andrew. > > > > "B.G." <B.G._member@pathlink.com> wrote in message news:d4tapi$p0n$1@digitaldaemon.com... >> >> Generally I'm looking for a 'nice' and portable way to be able to >> associate some >> arbitrary data with a particular thread. And, what's not less >> important to have >> a hook to be called when a thread ceases to exist, to throw it's >> associated >> information to the GC ! >> >> For example, I have a program with lots of string work... I >> thought of >> allocating a per-thread more-or-less persistant stringbuffer to >> minimize >> memory [de-]allocation. >> >> To be general there were many situations when I had headaches how >> to keep track >> of some THINGS commonly used throughout lots of different code. >> I thought of some options outlined below, but none of them seemes >> satisfactory >> to me. >> >> - move them along as function parameters or class members, (which >> I actually >> hated, for I hate redundancy) >> - make them global, leading to a less flexible solution >> (which I hate even more :-) >> - have a global pool of reusable items and lots of mutex stuff to >> make everything thread safe >> (I don't like this too, because it smells like a bottleneck) >> >> I thought, If there were a mechanism, clean, portable and >> efficient, to work >> with per-thread data, this were a nice option in SOME situations. >> >> Can someone suggest anything? >> >> > > |
May 01, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | But it's a useful option to have. And since D is garbage collected, it doesn't have the dangers C++ has with this same approach. Personally, I use this method pretty frequently, as it's quite convenient for "job" objects. Sean In article <d4v880$2gv0$1@digitaldaemon.com>, Matthew says... > >Doesn't help you much if you want to write a thread-agnostic library. > >"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d4tm9a$14pq$1@digitaldaemon.com... >> What about this? >> >> class MyTread: Tread >> { >> //.... your per-thread data.... >> override void run() >> { >> // ...usefull thread code... >> } >> } >> >> Am I missing something? >> >> Andrew. >> >> >> >> "B.G." <B.G._member@pathlink.com> wrote in message news:d4tapi$p0n$1@digitaldaemon.com... >>> >>> Generally I'm looking for a 'nice' and portable way to be able to >>> associate some >>> arbitrary data with a particular thread. And, what's not less >>> important to have >>> a hook to be called when a thread ceases to exist, to throw it's >>> associated >>> information to the GC ! >>> >>> For example, I have a program with lots of string work... I >>> thought of >>> allocating a per-thread more-or-less persistant stringbuffer to >>> minimize >>> memory [de-]allocation. >>> >>> To be general there were many situations when I had headaches how >>> to keep track >>> of some THINGS commonly used throughout lots of different code. >>> I thought of some options outlined below, but none of them seemes >>> satisfactory >>> to me. >>> >>> - move them along as function parameters or class members, (which >>> I actually >>> hated, for I hate redundancy) >>> - make them global, leading to a less flexible solution >>> (which I hate even more :-) >>> - have a global pool of reusable items and lots of mutex stuff to >>> make everything thread safe >>> (I don't like this too, because it smells like a bottleneck) >>> >>> I thought, If there were a mechanism, clean, portable and >>> efficient, to work >>> with per-thread data, this were a nice option in SOME situations. >>> >>> Can someone suggest anything? >>> >>> >> >> > > > |
May 01, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | "Sean Kelly" <sean@f4.ca> wrote in message news:d51c0l$1kh0$1@digitaldaemon.com... > But it's a useful option to have. And since D is garbage > collected, it doesn't > have the dangers C++ has with this same approach. Personally, I > use this method > pretty frequently, as it's quite convenient for "job" objects. Not sure what you mean by 'option'? Do you mean it's a useful technique? If so, I agree, but it still does not represent a viable broad solution. It represents an 'application-level' approach to threading, which is perfectly fine, and often the best solution, for many application-specific threading issues. But since it necessarily binds the code that needs/uses the per-thread opportunity, it cannot, by definition, be a general approach. (The only way that could be achieved would be by having the Thread class maintain a TSS dictionary, which would be at once type-unsafe and incredibly ineffecient.) So the need to true TSS remains. Maybe this'll just have to be on an ad-hoc basis up to D 1.2? :-) > Sean > > In article <d4v880$2gv0$1@digitaldaemon.com>, Matthew says... >> >>Doesn't help you much if you want to write a thread-agnostic library. >> >>"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d4tm9a$14pq$1@digitaldaemon.com... >>> What about this? >>> >>> class MyTread: Tread >>> { >>> //.... your per-thread data.... >>> override void run() >>> { >>> // ...usefull thread code... >>> } >>> } >>> >>> Am I missing something? >>> >>> Andrew. >>> >>> >>> >>> "B.G." <B.G._member@pathlink.com> wrote in message news:d4tapi$p0n$1@digitaldaemon.com... >>>> >>>> Generally I'm looking for a 'nice' and portable way to be able >>>> to >>>> associate some >>>> arbitrary data with a particular thread. And, what's not less >>>> important to have >>>> a hook to be called when a thread ceases to exist, to throw >>>> it's >>>> associated >>>> information to the GC ! >>>> >>>> For example, I have a program with lots of string work... I >>>> thought of >>>> allocating a per-thread more-or-less persistant stringbuffer to >>>> minimize >>>> memory [de-]allocation. >>>> >>>> To be general there were many situations when I had headaches >>>> how >>>> to keep track >>>> of some THINGS commonly used throughout lots of different code. >>>> I thought of some options outlined below, but none of them >>>> seemes >>>> satisfactory >>>> to me. >>>> >>>> - move them along as function parameters or class members, >>>> (which >>>> I actually >>>> hated, for I hate redundancy) >>>> - make them global, leading to a less flexible solution >>>> (which I hate even more :-) >>>> - have a global pool of reusable items and lots of mutex stuff >>>> to >>>> make everything thread safe >>>> (I don't like this too, because it smells like a bottleneck) >>>> >>>> I thought, If there were a mechanism, clean, portable and >>>> efficient, to work >>>> with per-thread data, this were a nice option in SOME >>>> situations. >>>> >>>> Can someone suggest anything? >>>> >>>> >>> >>> >> >> >> > > |
May 02, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | In article <d51e8j$1mdu$1@digitaldaemon.com>, Matthew says... > > >"Sean Kelly" <sean@f4.ca> wrote in message news:d51c0l$1kh0$1@digitaldaemon.com... >> But it's a useful option to have. And since D is garbage >> collected, it doesn't >> have the dangers C++ has with this same approach. Personally, I >> use this method >> pretty frequently, as it's quite convenient for "job" objects. > >Not sure what you mean by 'option'? Do you mean it's a useful technique? If so, I agree, but it still does not represent a viable broad solution. std.Thread class currently allows two methods to define thread procedures: class MyThread : Thread { override int run() { // do stuff } } or Thread t = new Thread( &threadFunc ); I said 'option' both because this is already possible with Phobos and because I think it should continue to be possible, even if it isn't the advertised method. But perhaps I should have said 'technique' instead :) >It represents an 'application-level' approach to threading, which is perfectly fine, and often the best solution, for many application-specific threading issues. But since it necessarily binds the code that needs/uses the per-thread opportunity, it cannot, by definition, be a general approach. I agree. Though in some respects I consider this to be a good thing, as the inheritance method shows rather explicitly that the code was inteded to be multithread-safe. >So the need to true TSS remains. Maybe this'll just have to be on an ad-hoc basis up to D 1.2? :-) By TSS do you mean thread-specific-storage? This might be possible for 1.0, as it's really a library issue, though this may require some work to have it play nice with the GC. I'll have to think about it a bit. Sean |
May 02, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | What about threads created by a D library or even worse, a C library?, Is it possible to 'bless' threads created by C libraries like UPnP SDK so that D can treat them like 'normal' D threads (for correct GC, etc.)? > >Doesn't help you much if you want to write a thread-agnostic library. Isn't there always at least one thread in every D application? I mean, you can always say Thread.getThis(), right? > > > >"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d4tm9a$14pq$1@digitaldaemon.com... >> What about this? >> >> class MyTread: Tread >> { >> //.... your per-thread data.... >> override void run() >> { >> // ...usefull thread code... >> } >> } >> >> Am I missing something? >> >> Andrew. >> >> >> >> "B.G." <B.G._member@pathlink.com> wrote in message news:d4tapi$p0n$1@digitaldaemon.com... >>> >>> Generally I'm looking for a 'nice' and portable way to be able to >>> associate some >>> arbitrary data with a particular thread. And, what's not less >>> important to have >>> a hook to be called when a thread ceases to exist, to throw it's >>> associated >>> information to the GC ! >>> >>> For example, I have a program with lots of string work... I >>> thought of >>> allocating a per-thread more-or-less persistant stringbuffer to >>> minimize >>> memory [de-]allocation. >>> >>> To be general there were many situations when I had headaches how >>> to keep track >>> of some THINGS commonly used throughout lots of different code. >>> I thought of some options outlined below, but none of them seemes >>> satisfactory >>> to me. >>> >>> - move them along as function parameters or class members, (which >>> I actually >>> hated, for I hate redundancy) >>> - make them global, leading to a less flexible solution >>> (which I hate even more :-) >>> - have a global pool of reusable items and lots of mutex stuff to >>> make everything thread safe >>> (I don't like this too, because it smells like a bottleneck) >>> >>> I thought, If there were a mechanism, clean, portable and >>> efficient, to work >>> with per-thread data, this were a nice option in SOME situations. >>> >>> Can someone suggest anything? >>> >>> >> >> > > > |
May 02, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to B.G. | In article <d56bhb$8ed$1@digitaldaemon.com>, B.G. says... > > >What about threads created by a D library or even worse, a C library?, Is it possible to 'bless' threads created by C libraries like UPnP SDK so that D can treat them like 'normal' D threads (for correct GC, etc.)? Not currently. The GC needs to be able to pause all running threads and to get stack/register pointers for those paused threads so it can scan them. Currently, this works by calling Thread.pauseAll() and then iterating across the collection returned by Thread.getAll(). You could try to fake this by deriving from std.Thread and implementing Thread.pause() and a few other functions for your new thread API. This *might* work, though some code that IMO should be in the Thread class (like the Windows routines that get a CONTEXT structure) are in the GC code instead, and this may or may not cause problems in practice. I rewrote this code in Ares, but I do consider it a requirement that all managed threads must be derived from std.Thread. This issue is somewhat related to how to handle DLL code, as the GCs need to cooperate at the very least. This may lead to some means of "registering" outside threads, but they will still likely need to be std.Thread objects for ease of use. Sean |
May 03, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | In article <d56e09$2ff$1@digitaldaemon.com>, Sean Kelly says... > >In article <d56bhb$8ed$1@digitaldaemon.com>, B.G. says... >> >> >>What about threads created by a D library or even worse, a C library?, Is it possible to 'bless' threads created by C libraries like UPnP SDK so that D can treat them like 'normal' D threads (for correct GC, etc.)? > >Not currently. The GC needs to be able to pause all running threads and to get stack/register pointers for those paused threads so it can scan them. Currently, this works by calling Thread.pauseAll() and then iterating across the collection returned by Thread.getAll(). You could try to fake this by deriving from std.Thread and implementing Thread.pause() and a few other functions for your new thread API. This *might* work, though some code that IMO should be in the Thread class (like the Windows routines that get a CONTEXT structure) are in the GC code instead, and this may or may not cause problems in practice. I rewrote this code in Ares, but I do consider it a requirement that all managed threads must be derived from std.Thread. > >This issue is somewhat related to how to handle DLL code, as the GCs need to cooperate at the very least. This may lead to some means of "registering" outside threads, but they will still likely need to be std.Thread objects for ease of use. > > >Sean > Hmmm, I'm just wondering, what could be a solution for cases like this: Given an SDK, written in C/C++, which produces it's own threads for whatever purposes. SDK assumes that the application built on top registers some callbacks to respond to some events. Now, what happens if we want to implement those callbacsk in D? They may get called from any thread, and If it's not the main thread there's apparently no way to teach D handle those threads correctly. I have an application written in C++ using a C SDK with the above architecture. And I want to port it to D for the sake of practice and trying D it the 'real world'. (...and because I got sick of smart pointers and weird syntax, long live D! ;-) Any suggestions? |
May 03, 2005 Re: custom per-thread stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to B.G. | In article <d56tdo$n7l$1@digitaldaemon.com>, B.G. says... > >Hmmm, I'm just wondering, what could be a solution for cases like this: > >Given an SDK, written in C/C++, which produces >it's own threads for whatever purposes. SDK assumes that the application built >on top registers some callbacks to respond to some events. > >Now, what happens if we want to implement those callbacsk in D? > >They may get called from any thread, and If it's not the main thread there's apparently no way to teach D handle those threads correctly. > >I have an application written in C++ using a C SDK with the above architecture. >And I want to port it to D for the sake of practice and trying D it the >'real world'. >(...and because I got sick of smart pointers and weird syntax, long live D! ;-) So you want to be able to pass pointers to GC memory to this C library and keep everything happy? You'll have to modify std.Thread, but how you go about it is up to you. Ares (an alternate std lib for D) defines three extern (C) functions that are used by the GC for this purpose: suspendAllThreads, scanAllThreads, and resumeAllThreads. Currently, these just forward the work to the appropriate static Thread methods, but it would be easy enough to add some code to support regitration of your custom thread API. Only catch here of course is that Ares is nowhere near as complete as Phobos. For a standard D distribution you'll need to modify the Thread class code to allow for pretty much the same thing. It might be a little hacky, but it should work just fine. Sean |
Copyright © 1999-2021 by the D Language Foundation