So far I've recorded these missing features:
I was wondering whether maybe other people miss features in Perl threads as well. If you do, please let them know. Maybe something already exists on CPAN that does the trick. Or maybe it is simple to implement and abstractify (is that a word?) into a module.
Any valid suggestions I will add to the above list.
Liz
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Missing (i)threads Features?
by BrowserUk (Patriarch) on Aug 20, 2003 at 16:06 UTC | |
A few thoughts so far Most of this stuff would be better, more easily and more efficiently done in threads.xs rather than requiring several extra modules each with its own state which (often) duplicates state already existing at the system level. Perhaps the powers that be would accept a threads::util module for this sort of stuff. I'm accutely aware that I am (legitimately) open to the critisism "Okay. Where are the patches?". The only response can give is "I'm working on it", but it going slowly:( To date, I still haven't succeeded in building perl with a free compiler such that it isn't emasculated (no large file support or PerlIO for example). Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller If I understand your problem, I can solve it! Of course, the same can be said for you. | [reply] [d/l] [select] |
by liz (Monsignor) on Aug 20, 2003 at 17:03 UTC | |
I agree. ...There is also a scheme for dynamically boosting a threads priority for short periods... Periods determined by what? Time? An event? (Un)Availability of a resource? ...yield actually yields, it would be better if yield where implemented to do something sensible--like sleep for short periods-- Hmmm... that's easily done if you're able to determine reliably that yield() is a no-op on your platform. ...create threads and suspend them pending some event... You could do something like that on Linux with Thread::Signal by creating a signal handler that, when called, will block on a variable, and another signal handler that resets that variable. Hmmm... I feel a module coming up... ;-) ...The situation is the 'pool of threads' scenario where you want to have the main thread block until one of the current threads has finished. I'm not sure what you mean, but are you sure this cannot be handled with Thread::Pool or Thread::Queue::Monitored or Thread::Conveyor::Monitored ? A minor critique of your current implementation of Thread::Running etc. is that I have to supply a list of threads to be checked That was the case in 0.01 ;-). In 0.02, the default for running(), tojoin() and exited() are all of the threads that Thread::Running knows about. Please RTFM ;-). Debugger support for threads needs improvement. I agree. I've created two debugging support modules for threads. Thread::Status which shows you where each thread is at a given time (unfortunately, only on Linux because of dependency on Thread::Signal) and Thread::Deadlock which will tell you where threads are when a deadlock occurs. ...view source around the current point on a thread by thread basis... I could add this as an option to Thread::Status. ...die ,warn and Carp should all include the thread id in their output by default in threaded applications. I actually submitted a patch for this before 5.8.0. The problem is that many tests depend on the format of die, warn and Carp, and it was breaking all sorts of tests ;-( At least, that's how I remember it (a lot has happened since). But I agree, yes! Most of this stuff would be better, more easily and more efficiently done in threads.xs rather than requiring several extra modules each with its own state which (often) duplicates state already existing at the system level. Perhaps the powers that be would accept a threads::util module for this sort of stuff. Patches welcome ;-). But not for 5.8.1, I'm afraid. Jarkko would go ballistic if anyone would start submitting patches for threads related stuff for inclusion in 5.8.1... ;-) To date, I still haven't succeeded in building perl with a free compiler such that it isn't emasculated (no large file support or PerlIO for example). ??? on what system? Liz | [reply] |
by BrowserUk (Patriarch) on Aug 21, 2003 at 20:12 UTC | |
Periods determined by what? Time? An event? (Un)Availability of a resource? The way this works is: If a thread is designated as being in a 'dynamic priority class' and 'priority boosting' is enabled, then when the thread is 'woken' after a wait state (asynchronous IO completion, timer expiry or the like), then the OS temporarially boosts it's priority. The effect is that when whatever thread (system wide rather than process wide) that was running when the asynchronous event occured, completes it's timeslot, the thread that was waiting on that event has a higher (but not exclusive) chance of being selected as the next thread to be run by the scheduler. The threads priority returns to its unboosted level the next time it is run. This provides a mechanism for the application to increase the probability that time-critical threads run as soon as possible once they have something to do without risking overriding higher priority threads elsewhere in the system as would be the case if this was done in a completely deterministic way. That's a poor destription, but may be good enough. That's easily done if you're able to determine reliably that yield() is a no-op on your platform. I guess what I am saying here is that if a platform has a sensible alternative to a native yield(), then it would be better if that alternative was provided by the threads module by default rather than requiring an extra piece of code that every user needs to use to determine if they need to add another piece of code to work around that fact that it isn't available by default, and then force everyone to come up with their own alternative implementation. Commensurate with that, it would be better to have the yield() function raise an exception on those platforms that do not implement it rather than needing to add on a module to detect that it is a no-op. ... on Linux with Thread::Signal... The problem with that is that it won't work on platforms that don't support signals. It is also adding layers on top of the threads API in a way that makes it difficult to code cross-platform. The extra layers also make for very complicated debugging. I'm not saying that it isn't the right way to do it on Linux, only that at the architectural level, if it is going to be possible to write cross-platform threaded applications in perl, then the API's available need to be integrated at higher level than can really be done by add-ons written at the perl level. In this case, on Win32, SuspendThread and ResumeThread translate directly to native APIs. Then only thing missing is access to the native thread handle. It's actually quite easy to obtain this handle as there is a native API that will return a usable handle for the currently running thread, which may or may not be the same as the native handle stored within the threads module. The problem comes to trying to devine what effect using this to suspend a thread externally to the threads module will have upon the perls management of that thread? Maybe if the thread is suspended, nothing untoward will happen, but maybe Perl will take umbrage at having one of it's threads rendered un-runnable without it being consulted:) With regard to your many Thread::* modules. The problem (from my Win32 platform perspective) is that many of them rely entirely upon platform-dependant idioms like Signals. I can see how to implement most, if not all of them on the Win32 platform, but not in a way that would make them compatible with the modules you have already written. This would make life very tough for anyone trying to utilise them for cross-platform development. This is where trying to find a platform independant iThreads API set would be useful. If (we?) could take a step back from specific implementations and try and look at what features would be useful to have and try to encapsulate those features within an API that would enable them to implemented reasonably efficiently on all (or at least most) platforms, then it might be possible to come up with something that would be truely usable. ...many tests depend on the format of die, warn and Carp... Perhaps the solution here is for the patch(es) to die, warn and Carp to detect whether threads were being used and only use the modified form if they were? That would leave existing non-threaded testcases unaffected. Patches welcome ;-). But not for 5.8.1... Rather than patching the existing threads module directly, I was thinking more of coming up with a single threads::util module that would have access to the internal structures (native thread handles etc.) that encapsulated all of the new APIs. Whether that was later adopted or integrated could be left for powers-that-be to decide later on. on what system? Win32. I tried MingW, Borland and LCC so far. I get furthest with Borland, but its STDIO libraries don't have huge file (>4GB) support. Theoretically, using PerlIO ought to work around this, but as currently implemented (for Win32 at least), PerlIO still relies on STDIO calls for fseek(), fstat() and ftell(). I ought to be able to work around this by modifying the Win32_... verions of the three APIs in win32.c to use the native APi equivalents rather than the C-library versions, but this is not trivial as they all require access to the handle that is their first parameter and this is not exposed by the C-libraries. I've searched the web hoping that Borland or someone else would have already released extensions to accomodate huge files, without success. I've also looked to see if the source code for the libraries was available to no avail. I'm currently trying to reverse engineer the FILE * structure, but as many of the fields are bit-fields, and the structure is used ubiquitously through out the libraries and these libraries are in turn used extensively when building perl, reverse engineering it and all the constants required to access and manipulate them is a distinctly non-trivial process. The bigggest barrier to making changes to the perl build process is the incredibly conveluted and incestuous nature of the build mechanisms. (D|N)MAKE is used to build mini-perl, which is used to process header files into a config which is used to create makfiles which use perl to create header files which are processed using perl to ..... I think I got lost somewhere in a maze of dark twisty passages. Combine that with the conditional compilation directives in every source module to account for all the disperate platform differences and it is amazing that perl manages to build anywhere. That it is seccessful in doing so on so many platforms is truely remarkable and a testimony to losts of hard work by lots if people. The problem is that the hands of all those individuals show and the while thing is now so complex that it a huge investment of time and expertise to even begin to make inroads into the process. I have had lots of time, and whilst my skill levels may not be upto the standards of those that precede me, I'm not exactly clueless. I've spent several months trying to get a handle on the while thing and still it defeats me. Even where I have made so progress and have seen things that I might like to do, I am reluctant to try because I feel that making further piecemeal changes is likely to simply perpectuate and add to the problems I see. And each time someone, somewhere makes changes and additions that add to the complexity, it further removes the whole process from the 'ordinary man or woman', by which I mean thise that don't have the luxury of unlimited time and high levels of expertise to devote. Step by step, this means that fewer and fewer people will ever be able to contribute to the perl codebase and leave more and more people dependant upon the time, skills and motivation of fewer and fewer experts. From my persepctive, this is tantamount to the death-knell for an open source project. I think I understand why Perl 6 is going for a clean sweep rather than trying to further extend the existing. I think that the greatest service that could be performed for the Perl 5 source is for someone to discard the existing build process and start again. I've had 2 or 3 attempts at starting this process, but you need to be a computer to be able to resolve all the paths and inter-dependancies. Trying to unwind them is nearly impossible for a human being--at least it is for this human being. I'm afraid I've had to give up on that approach. Please excuse any typos, but hopefully everything is understandable. Life is too short to pander to anal-retentive pedants who specialise in braying about the syntax instead of concentrating in the symantics. Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller If I understand your problem, I can solve it! Of course, the same can be said for you. | [reply] [d/l] [select] |
by liz (Monsignor) on Aug 22, 2003 at 16:06 UTC | |
by BrowserUk (Patriarch) on Aug 22, 2003 at 18:57 UTC | |
Thread::Suspend uploaded
by liz (Monsignor) on Aug 22, 2003 at 13:36 UTC | |
NAME Thread::Suspend - suspend and resume threads from another thread SYNOPSIS use Thread::Suspend; # exports suspend() and resume() use Thread::Suspend qw(suspend); # only exports suspend() use Thread::Suspend (); # threads class methods only my $thread = threads->new( sub { whatever } ); $thread->suspend; # suspend thread by object threads->suspend( $thread ); # also threads->suspend( $tid ); # suspend by thread ID threads->suspend; # suspend all (other) threads $thread->resume; # resume a single thread threads->resume; # resume all suspended threadsUnfortunately, this depends on Thread::Signal, so it currently only works on Linux. Liz | [reply] |