Thread programming model
[email protected] (Steven W McDougall) Fri, 18 Aug 2000 11:36:06 -0400 (EDT)
| Newsgroups | perl.perl6.language.flow |
|---|---|
| Message-ID | <[email protected]> |
I've spent the last 3 years programming WindowsNT threads in MSVC++, and I *really* like it. I want similar capabilities in Perl6. 1 The C++ thread model Here is the thread model that I have in C++. It is a starting point for thinking about what I want in Perl. Every thread sees - the same code - the same globals - the same heap Each thread has its own stack. Threads can obtain thread-local global storage. I've never needed to do this. For synchronization, I have - critical sections - mutexes - semaphores - events - timers - timeouts - select - wait for thread termination - wait for all - wait for any 2. A Perl6 thread model Here is the model that I want in Perl6 Every thread sees - the same global stash - the same code Every thread has - its own subroutine stack - its own copy of all its lexicals Each thread gets a thread-local global stash. $main::foo names a variable in the global stash; by analogy, $thread::foo could name a variable in the thread-local stash. $foo means $main::foo, just like in Perl5. If you want $thread::foo, you have to write $thread::foo. The language provides all the synchronization primitives listed above. 3. Modules and re-entrancy RFC1v2 objects to this model on the grounds that modules won't be reentrant if they see the same globals in different threads. I think this is the tail wagging the dog. 3.1 Programs need globals The reason I like threads is that I can write some code, spin off some threads, and then share data between them. If every thread sees a different copy of the globals, then I might as well fork processes. 3.2 Modules shouldn't use globals If you want your modules to be reentrant, then you have to write them that way. Rule 1 is *no globals*. The most common use of modules is to implement an object, and the object should get everything it needs from its instance data. This isn't just a threading issue: it is basic OO practice, going all the way back to perlobj.pod in 1995. Existing Perl5 modules may well turn out not to be reentrant. The solution to that is to rewrite the modules, not contort Perl6 to accommodate them. 4. use foo RFC1v2 has some discussion of how a thread can use a module. If all threads share the global stash, then this problem goes away. A use statement compiles a module and installs its symbols in the global stash at compile time. Threaded code finds its global symbols (primarily subroutine names) in the global stash, just like non-threaded code. The only way that a thread can execute a use statement is with eval; writing eval "use foo"; inside a thread is liable to redefine subroutines in the global stash. Avoiding race conditions when this happens is a user-level synchronization problem. - SWM