ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro-Multicore/Multicore.pm
(Generate patch)

Comparing Coro-Multicore/Multicore.pm (file contents):
Revision 1.9 by root, Mon Jul 27 12:05:09 2015 UTC vs.
Revision 1.10 by root, Mon Jul 27 14:32:33 2015 UTC

7 # when you DO control the main event loop, e.g. in the main program 7 # when you DO control the main event loop, e.g. in the main program
8 8
9 use Coro::Multicore; # enable by default 9 use Coro::Multicore; # enable by default
10 10
11 Coro::Multicore::scoped_disable; 11 Coro::Multicore::scoped_disable;
12 EV::loop; # or AnyEvent::Loop::run, Event::loop, AE::cv->recv, ... 12 AE::cv->recv; # or EV::loop, AnyEvent::Loop::run, Event::loop, ...
13 13
14 # when you DO NOT control the event loop, e.g. in a module on CPAN 14 # when you DO NOT control the event loop, e.g. in a module on CPAN
15 # do nothing (see HOW TO USE IT) or something like this:
15 16
16 use Coro::Multicore (); # disable by default 17 use Coro::Multicore (); # disable by default
17 18
18 async { 19 async {
19 Coro::Multicore::scoped_enable; 20 Coro::Multicore::scoped_enable;
36conditions: firstly, the coro thread executes in XS code and does not 37conditions: firstly, the coro thread executes in XS code and does not
37touch any perl data structures, and secondly, the XS code is specially 38touch any perl data structures, and secondly, the XS code is specially
38prepared to allow this. 39prepared to allow this.
39 40
40This means that, when you call an XS function of a module prepared for it, 41This means that, when you call an XS function of a module prepared for it,
41this XS function can execute in parallel to any other Coro threads. 42this XS function can execute in parallel to any other Coro threads. This
43is useful for both CPU bound tasks (such as cryptography) as well as I/O
44bound tasks (such as loading an image from disk). It can also be used
45to do stuff in parallel via APIs that were not meant for this, such as
46database accesses via DBI.
42 47
43The mechanism to support this is easily added to existing modules 48The mechanism to support this is easily added to existing modules
44and is independent of L<Coro> or L<Coro::Multicore>, and therefore 49and is independent of L<Coro> or L<Coro::Multicore>, and therefore
45could be used, without changes, with other, similar, modules, or even 50could be used, without changes, with other, similar, modules, or even
46the perl core, should it gain real thread support anytime soon. See 51the perl core, should it gain real thread support anytime soon. See
51This module is an L<AnyEvent> user (and also, if not obvious, uses 56This module is an L<AnyEvent> user (and also, if not obvious, uses
52L<Coro>). 57L<Coro>).
53 58
54=head1 HOW TO USE IT 59=head1 HOW TO USE IT
55 60
56It could hardly be simpler - if you use coro threads, and before you call 61Quick explanation: decide whether you control the main program/the event
57a supported lengthy operation implemented in XS, use this module and other 62loop and choose one of the two styles from the SYNOPSIS.
58coro threads can run in parallel:
59 63
64Longer explanation: There are two major modes this module can used in -
65supported operations run asynchronously either by default, or only when
66requested. The reason you might not want to enable this module for all
67operations by default is compatibility with existing code:
68
69Since this module integrates into an event loop and you must not normally
70block and wait for something in an event loop callbacks. Now imagine
71somebody patches your favourite module (e.g. Digest::MD5) to take
72advantage of of the Perl Multicore API.
73
74Then code that runs in an event loop callback and executes
75Digest::MD5::md5 would work fine without C<Coro::Multicore> - it would
76simply calculate the MD5 digest and block execution of anything else. But
77with C<Coro::Multicore> enabled, the same operation would try to run other
78threads. And when those wait for events, there is no event loop anymore,
79as the event loop thread is busy doing the MD5 calculation, leading to a
80deadlock.
81
82=head2 USE IT IN THE MAIN PROGRAM
83
84One way to avoid this is to not run perlmulticore enabled functions
85in any callbacks. A simpler way to snure it works is to disable
86C<Coro::Multicore> thread switching in event loop callbacks, and enable it
87everywhere else.
88
89Therefore, if you control the event loop, as is usually the case when
90you write I<program> and not a I<module>, then you can enable C<Coro::Multicore>
91by default, and disable it in your event loop thread:
92
93 # example 1, separate thread for event loop
94
95 use EV;
96 use Coro;
60 use Coro::Multicore; 97 use Coro::Multicore;
61 98
62This module has no important API functions to learn or remember. All you 99 async {
63need to do is I<load> it before you can take advantage of it. 100 Coro::Multicore::scoped_disable;
101 EV::loop;
102 };
103
104 # do something else
105
106 # example 2, run event loop as main program
107
108 use EV;
109 use Coro;
110 use Coro::Multicore;
111
112 Coro::Multicore::scoped_disable;
113
114 ... initialisation
115
116 EV::loop;
117
118The latter form is usually better and more idiomatic - the main thread is
119the best place to run the event loop.
120
121=head2 USE IT IN A MODULE
122
123When you I<do not> control the event loop, for example, because you want
124to use this from a module you published on CPAN, then the previous method
125doesn't work.
126
127However, this is not normally a problem in practise - most modules only
128do work at request of the caller. In that case, you might not care
129whether it does block other threads or not, as this would be the callers
130responsibility (or decision), and by extension, a decision for the main
131program.
132
133So unless you use XS and want your XS functions to run asynchronously,
134you don't have to worry about C<Coro::Multicore> at all - if you
135happen to call XS functions that are multicore-enabled and your
136caller has configured things correctly, they will automatically run
137asynchronously. Or in other words: nothing needs to be done at all, which
138also means that this method works fine for existing pure-perl modules,
139without having to change them at all.
140
141Only if your module runs it's own L<Coro> threads could it be an
142issue - maybe your module implements some kind of job pool and relies
143on certain operations to run asynchronously. Then you can still use
144C<Coro::Multicore> by not enabling it be default and only enabling it in
145your own threads:
146
147 use Coro;
148 use Coro::Multicore (); # note the () to disable by default
149
150 async {
151 Coro::Multicore::scoped_enable;
152
153 # do things asynchronously by calling perlmulticore-enabled functions
154 };
64 155
65=head2 EXPORTS 156=head2 EXPORTS
66 157
67This module does not (at the moment) export any symbols. It does, however, 158This module does not (at the moment) export any symbols. It does, however,
68export "behaviour" - if you use the default import, then Coro::Multicore 159export "behaviour" - if you use the default import, then Coro::Multicore
93This function enables (if C<$enable> is true) or disables (if C<$enable> 184This function enables (if C<$enable> is true) or disables (if C<$enable>
94is false) the multicore functionality globally. By default, it is enabled. 185is false) the multicore functionality globally. By default, it is enabled.
95 186
96This can be used to effectively disable this module's functionality by 187This can be used to effectively disable this module's functionality by
97default, and enable it only for selected threads or scopes, by calling 188default, and enable it only for selected threads or scopes, by calling
98C<Coro::Multicore::scope_enable>. 189C<Coro::Multicore::scoped_enable>.
99 190
100The function returns the previous value of the enable flag. 191The function returns the previous value of the enable flag.
101 192
102=item Coro::Multicore::scoped_enable 193=item Coro::Multicore::scoped_enable
103 194
120 211
121use Coro (); 212use Coro ();
122use AnyEvent (); 213use AnyEvent ();
123 214
124BEGIN { 215BEGIN {
125 our $VERSION = 0.02; 216 our $VERSION = 0.03;
126 217
127 use XSLoader; 218 use XSLoader;
128 XSLoader::load __PACKAGE__, $VERSION; 219 XSLoader::load __PACKAGE__, $VERSION;
129} 220}
130 221
137 228
138 enable 1; 229 enable 1;
139} 230}
140 231
141our $WATCHER = AE::io fd, 0, \&poll; 232our $WATCHER = AE::io fd, 0, \&poll;
233
234=head1 THREAD SAFETY OF SUPPORTING XS MODULES
235
236Just because an XS module supports perlmulticore might not immediately
237make it reentrant. For example, while you can (try to) call C<execute>
238on the same database handle for the patched C<DBD::mysql> (see the
239L<registry|http://perlmulticore.schmorp.de/registry>), this will almost
240certainly not work, despite C<DBD::mysql> and C<libmysqlclient> being
241thread safe and reentrant - just not on the same database handle.
242
243Many modules have limitations such as these - some can only be called
244concurrently from a single thread as they use global variables, some
245can only be called concurrently on different I<handles> (e.g. database
246connections for DBD modules, or digest objects for Digest modules),
247and some can be called at any time (such as the C<md5> function in
248C<Digest::MD5>).
249
250Generally, you only have to be careful with the very few modules that use
251global variables or rely on C libraries that aren't thread-safe, which
252should be documented clearly in the module documentation.
253
254Most modules are either perfectly reentrant, or at least reentrant as long
255as you give every thread it's own I<handle> object.
256
257=head1 EXCEPTIONS AND THREAD CANCELLATION
258
259L<Coro> allows you to cancel threads even when they execute within an XS
260function (C<cancel> vs. C<cancel> methods). Similarly, L<Coro> allows you
261to send exceptions (e.g. via the C<throw> method) to threads executing
262inside an XS function.
263
264While doing this is questionable and dangerous with normal Coro threads
265already, they are both supported in this module, although with potentially
266unwanted effects. The following describes the current implementation and
267is subject to change. It is described primarily so you can understand what
268went wrong, if things go wrong.
269
270=over 4
271
272=item EXCEPTIONS
273
274When a thread that has currently released the perl interpreter (e.g.
275because it is executing a perlmulticore enabled XS function) receives an exception, it will
276at first continue normally.
277
278After acquiring the perl interpreter again, it will throw the
279exception it previously received. More specifically, when a thread
280calls C<perlinterp_acquire ()> and has received an exception, then
281C<perlinterp_acquire ()> will not return but instead C<die>.
282
283Most code that has been updated for perlmulticore support will not expect
284this, and might leave internal state corrupted to some extent.
285
286=item CANCELLATION
287
288Unsafe cancellation on a thread that has released the perl interpreter
289frees its resources, but let's the XS code continue at first. This should
290not lead to corruption on the perl level, as the code isn't allowed to
291touch perl data structures until it reacquires the interpreter.
292
293The call to C<perlinterp_acquire ()> will then block indefinitely, leaking
294the (OS level) thread.
295
296Safe cancellation will simply fail in this case, so is still "safe" to
297call.
298
299=back
142 300
143=head1 INTERACTION WITH OTHER SOFTWARE 301=head1 INTERACTION WITH OTHER SOFTWARE
144 302
145This module is very similar to other environments where perl interpreters 303This module is very similar to other environments where perl interpreters
146are moved between threads, such as mod_perl2, and the same caveats apply. 304are moved between threads, such as mod_perl2, and the same caveats apply.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines