⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlthrtut.pod

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 POD
📖 第 1 页 / 共 4 页
字号:
the thread must have found a new prime number.  In that case, a newchild thread is created for that prime and stuck on the end of thepipeline.This probably sounds a bit more confusing than it really is, so let'sgo through this program piece by piece and see what it does.  (Forthose of you who might be trying to remember exactly what a primenumber is, it's a number that's only evenly divisible by itself and 1.)The bulk of the work is done by the C<check_num()> subroutine, whichtakes a reference to its input queue and a prime number that it'sresponsible for.  After pulling in the input queue and the prime thatthe subroutine is checking (line 20), we create a new queue (line 22)and reserve a scalar for the thread that we're likely to create later(line 21).The while loop from lines 23 to line 31 grabs a scalar off the inputqueue and checks against the prime this thread is responsiblefor.  Line 24 checks to see if there's a remainder when we divide thenumber to be checked by our prime.  If there is one, the numbermust not be evenly divisible by our prime, so we need to either passit on to the next thread if we've created one (line 26) or create anew thread if we haven't.The new thread creation is line 29.  We pass on to it a reference tothe queue we've created, and the prime number we've found.Finally, once the loop terminates (because we got a 0 or C<undef> in thequeue, which serves as a note to terminate), we pass on the notice to ourchild and wait for it to exit if we've created a child (lines 32 and35).Meanwhile, back in the main thread, we first create a queue (line 10) andqueue up all the numbers from 3 to 1000 for checking (lines 11-13),plus a termination notice (line 14).  Then we create the initial childthreads (line 16), passing it the queue and the first prime: 2.  Finally,we wait for the first child thread to terminate (line 17).  Because achild won't terminate until its child has terminated, we know that we'redone once we return from the C<join()>.That's how it works.  It's pretty simple; as with many Perl programs,the explanation is much longer than the program.=head1 Different implementations of threadsSome background on thread implementations from the operating systemviewpoint.  There are three basic categories of threads: user-mode threads,kernel threads, and multiprocessor kernel threads.User-mode threads are threads that live entirely within a program andits libraries.  In this model, the OS knows nothing about threads.  Asfar as it's concerned, your process is just a process.This is the easiest way to implement threads, and the way most OSesstart.  The big disadvantage is that, since the OS knows nothing aboutthreads, if one thread blocks they all do.  Typical blocking activitiesinclude most system calls, most I/O, and things like C<sleep()>.Kernel threads are the next step in thread evolution.  The OS knowsabout kernel threads, and makes allowances for them.  The maindifference between a kernel thread and a user-mode thread isblocking.  With kernel threads, things that block a single thread don'tblock other threads.  This is not the case with user-mode threads,where the kernel blocks at the process level and not the thread level.This is a big step forward, and can give a threaded program quite aperformance boost over non-threaded programs.  Threads that blockperforming I/O, for example, won't block threads that are doing otherthings.  Each process still has only one thread running at once,though, regardless of how many CPUs a system might have.Since kernel threading can interrupt a thread at any time, they willuncover some of the implicit locking assumptions you may make in yourprogram.  For example, something as simple as C<$a = $a + 2> can behaveunpredictably with kernel threads if C<$a> is visible to otherthreads, as another thread may have changed C<$a> between the time itwas fetched on the right hand side and the time the new value isstored.Multiprocessor kernel threads are the final step in threadsupport.  With multiprocessor kernel threads on a machine with multipleCPUs, the OS may schedule two or more threads to run simultaneously ondifferent CPUs.This can give a serious performance boost to your threaded program,since more than one thread will be executing at the same time.  As atradeoff, though, any of those nagging synchronization issues thatmight not have shown with basic kernel threads will appear with avengeance.In addition to the different levels of OS involvement in threads,different OSes (and different thread implementations for a particularOS) allocate CPU cycles to threads in different ways.Cooperative multitasking systems have running threads give up controlif one of two things happen.  If a thread calls a yield function, itgives up control.  It also gives up control if the thread doessomething that would cause it to block, such as perform I/O.  In acooperative multitasking implementation, one thread can starve all theothers for CPU time if it so chooses.Preemptive multitasking systems interrupt threads at regular intervalswhile the system decides which thread should run next.  In a preemptivemultitasking system, one thread usually won't monopolize the CPU.On some systems, there can be cooperative and preemptive threadsrunning simultaneously. (Threads running with realtime prioritiesoften behave cooperatively, for example, while threads running atnormal priorities behave preemptively.)Most modern operating systems support preemptive multitasking nowadays.=head1 Performance considerationsThe main thing to bear in mind when comparing Perl's I<ithreads> to other threadingmodels is the fact that for each new thread created, a complete copy ofall the variables and data of the parent thread has to be taken. Thus,thread creation can be quite expensive, both in terms of memory usage andtime spent in creation. The ideal way to reduce these costs is to have arelatively short number of long-lived threads, all created fairly earlyon -- before the base thread has accumulated too much data. Of course, thismay not always be possible, so compromises have to be made. However, aftera thread has been created, its performance and extra memory usage shouldbe little different than ordinary code.Also note that under the current implementation, shared variablesuse a little more memory and are a little slower than ordinary variables.=head1 Process-scope ChangesNote that while threads themselves are separate execution threads andPerl data is thread-private unless explicitly shared, the threads canaffect process-scope state, affecting all the threads.The most common example of this is changing the current workingdirectory using C<chdir()>.  One thread calls C<chdir()>, and the workingdirectory of all the threads changes.Even more drastic example of a process-scope change is C<chroot()>:the root directory of all the threads changes, and no thread canundo it (as opposed to C<chdir()>).Further examples of process-scope changes include C<umask()> andchanging uids and gids.Thinking of mixing C<fork()> and threads?  Please lie down and waituntil the feeling passes.  Be aware that the semantics of C<fork()> varybetween platforms.  For example, some UNIX systems copy all the currentthreads into the child process, while others only copy the thread thatcalled C<fork()>. You have been warned!Similarly, mixing signals and threads may be problematic.Implementations are platform-dependent, and even the POSIXsemantics may not be what you expect (and Perl doesn't evengive you the full POSIX API).  For example, there is no way toguarantee that a signal sent to a multi-threaded Perl applicationwill get intercepted by any particular thread.  (However, a recentlyadded feature does provide the capability to send signals betweenthreads.  See L<threads/"THREAD SIGNALLING> for more details.)=head1 Thread-Safety of System LibrariesWhether various library calls are thread-safe is outside the controlof Perl.  Calls often suffering from not being thread-safe include:C<localtime()>, C<gmtime()>,  functions fetching user, group andnetwork information (such as C<getgrent()>, C<gethostent()>,C<getnetent()> and so on), C<readdir()>,C<rand()>, and C<srand()> -- in general, calls that depend on some globalexternal state.If the system Perl is compiled in has thread-safe variants of suchcalls, they will be used.  Beyond that, Perl is at the mercy ofthe thread-safety or -unsafety of the calls.  Please consult yourC library call documentation.On some platforms the thread-safe library interfaces may fail if theresult buffer is too small (for example the user group databases maybe rather large, and the reentrant interfaces may have to carry arounda full snapshot of those databases).  Perl will start with a smallbuffer, but keep retrying and growing the result bufferuntil the result fits.  If this limitless growing sounds bad forsecurity or memory consumption reasons you can recompile Perl withC<PERL_REENTRANT_MAXSIZE> defined to the maximum number of bytes you willallow.=head1 ConclusionA complete thread tutorial could fill a book (and has, many times),but with what we've covered in this introduction, you should be wellon your way to becoming a threaded Perl expert.=head1 SEE ALSOAnnotated POD for L<threads>:L<http://annocpan.org/?mode=search&field=Module&name=threads>Lastest version of L<threads> on CPAN:L<http://search.cpan.org/search?module=threads>Annotated POD for L<threads::shared>:L<http://annocpan.org/?mode=search&field=Module&name=threads%3A%3Ashared>Lastest version of L<threads::shared> on CPAN:L<http://search.cpan.org/search?module=threads%3A%3Ashared>Perl threads mailing list:L<http://lists.cpan.org/showlist.cgi?name=iThreads>=head1 BibliographyHere's a short bibliography courtesy of J黵gen Christoffel:=head2 Introductory TextsBirrell, Andrew D. An Introduction to Programming withThreads. Digital Equipment Corporation, 1989, DEC-SRC Research Report#35 online ashttp://gatekeeper.dec.com/pub/DEC/SRC/research-reports/abstracts/src-rr-035.html(highly recommended)Robbins, Kay. A., and Steven Robbins. Practical Unix Programming: AGuide to Concurrency, Communication, andMultithreading. Prentice-Hall, 1996.Lewis, Bill, and Daniel J. Berg. Multithreaded Programming withPthreads. Prentice Hall, 1997, ISBN 0-13-443698-9 (a well-writtenintroduction to threads).Nelson, Greg (editor). Systems Programming with Modula-3.  PrenticeHall, 1991, ISBN 0-13-590464-1.Nichols, Bradford, Dick Buttlar, and Jacqueline Proulx Farrell.Pthreads Programming. O'Reilly & Associates, 1996, ISBN 156592-115-1(covers POSIX threads).=head2 OS-Related ReferencesBoykin, Joseph, David Kirschen, Alan Langerman, and SusanLoVerso. Programming under Mach. Addison-Wesley, 1994, ISBN0-201-52739-1.Tanenbaum, Andrew S. Distributed Operating Systems. Prentice Hall,1995, ISBN 0-13-219908-4 (great textbook).Silberschatz, Abraham, and Peter B. Galvin. Operating System Concepts,4th ed. Addison-Wesley, 1995, ISBN 0-201-59292-4=head2 Other ReferencesArnold, Ken and James Gosling. The Java Programming Language, 2nded. Addison-Wesley, 1998, ISBN 0-201-31006-6.comp.programming.threads FAQ,L<http://www.serpentine.com/~bos/threads-faq/>Le Sergent, T. and B. Berthomieu. "Incremental MultiThreaded GarbageCollection on Virtually Shared Memory Architectures" in MemoryManagement: Proc. of the International Workshop IWMM 92, St. Malo,France, September 1992, Yves Bekkers and Jacques Cohen, eds. Springer,1992, ISBN 3540-55940-X (real-life thread applications).Artur Bergman, "Where Wizards Fear To Tread", June 11, 2002,L<http://www.perl.com/pub/a/2002/06/11/threads.html>=head1 AcknowledgementsThanks (in no particular order) to Chaim Frenkel, Steve Fink, GurusamySarathy, Ilya Zakharevich, Benjamin Sugars, J黵gen Christoffel, JoshuaPritikin, and Alan Burlison, for their help in reality-checking andpolishing this article.  Big thanks to Tom Christiansen for his rewriteof the prime number generator.=head1 AUTHORDan Sugalski E<lt>dan@sidhe.org<gt>Slightly modified by Arthur Bergman to fit the new thread model/module.Reworked slightly by J鰎g Walter E<lt>jwalt@cpan.org<gt> to be more conciseabout thread-safety of Perl code.Rearranged slightly by Elizabeth Mattijsen E<lt>liz@dijkmat.nl<gt> to putless emphasis on yield().=head1 CopyrightsThe original version of this article originally appeared in The PerlJournal #10, and is copyright 1998 The Perl Journal. It appears courtesyof Jon Orwant and The Perl Journal.  This document may be distributedunder the same terms as Perl itself.=cut

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -