forked from UWPCE-PythonCert/ProgrammingInPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadingMultiprocessing.html
More file actions
817 lines (771 loc) · 59.2 KB
/
ThreadingMultiprocessing.html
File metadata and controls
817 lines (771 loc) · 59.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Threading and multiprocessing — Programming in Python 7.0 documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Threaded Web Scraper" href="../exercises/threaded_downloader.html" />
<link rel="prev" title="Notes on Coroutines" href="Coroutines.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #4b2e83" >
<a href="../index.html">
<img src="../_static/UWPCE_logo_full.png" class="logo" alt="Logo"/>
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Topics in the Program</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../topics/01-setting_up/index.html">1. Setting up your Environment</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/02-basic_python/index.html">2. Basic Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/03-recursion_booleans/index.html">3. Booleans and Recursion</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/04-sequences_iteration/index.html">4. Sequences and Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/05-text_handling/index.html">5. Basic Text Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/06-exceptions/index.html">6. Exception Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/07-unit_testing/index.html">7. Unit Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/08-dicts_sets/index.html">8. Dictionaries and Sets</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/09-files/index.html">9. File Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/10-modules_packages/index.html">10. Modules and Packages</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/11-argument_passing/index.html">11. Advanced Argument Passing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/12-comprehensions/index.html">12. Comprehensions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/13-intro_oo/index.html">13. Intro to Object Oriented Programing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/14-magic_methods/index.html">14. Properties and Magic Methods</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/15-subclassing/index.html">15. Subclassing and Inheritance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/16-multiple_inheritance/index.html">16. Multiple Inheritance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/17-functional_programming/index.html">17. Introduction to Functional Programming</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/18-advanced_testing/index.html">18. Advanced Testing</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../topics/99-extras/index.html">19. Extra Topics</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Pep8.html">Coding Style and Linting</a></li>
<li class="toctree-l2"><a class="reference internal" href="CodeReviews.html">Code Reviews</a></li>
<li class="toctree-l2"><a class="reference internal" href="PersistanceAndSerialization.html">Persistence and Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="Unicode.html">Unicode in Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="IteratorsAndGenerators.html">Iterators and Generators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Decorators.html">Decorators</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/mailroom/mailroom-decorator.html">Mailroom – Decoratoring it</a></li>
<li class="toctree-l2"><a class="reference internal" href="ContextManagers.html">Context Managers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/context-managers-exercise.html">A Couple Handy Context Managers</a></li>
<li class="toctree-l2"><a class="reference internal" href="MetaProgramming.html">Metaprogramming</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/mailroom/mailroom-meta.html">Mailroom – metaprogramming it!</a></li>
<li class="toctree-l2"><a class="reference internal" href="Logging.html">Logging and the logging module</a></li>
<li class="toctree-l2"><a class="reference internal" href="Debugging.html">Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoSQL.html">No SQL Databases</a></li>
<li class="toctree-l2"><a class="reference internal" href="GraphDatabases.html">Graph Databases</a></li>
<li class="toctree-l2"><a class="reference internal" href="Concurrency.html">Concurrent Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="Async.html">Asychronous Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="Coroutines.html">Notes on Coroutines</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Threading and multiprocessing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/threaded_downloader.html">Threaded Web Scraper</a></li>
<li class="toctree-l2"><a class="reference internal" href="Profiling.html">Performance and Profiling</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #4b2e83" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Programming in Python</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content style-external-links">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home"></a> »</li>
<li><a href="../topics/99-extras/index.html"><span class="section-number">19. </span>Extra Topics</a> »</li>
<li>Threading and multiprocessing</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/modules/ThreadingMultiprocessing.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul><div class="rst-breadcrumbs-buttons" role="navigation" aria-label="Sequential page navigation">
<a href="Coroutines.html" class="btn btn-neutral float-left" title="Notes on Coroutines" accesskey="p"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../exercises/threaded_downloader.html" class="btn btn-neutral float-right" title="Threaded Web Scraper" accesskey="n">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="threading-and-multiprocessing">
<span id="threading"></span><h1>Threading and multiprocessing<a class="headerlink" href="#threading-and-multiprocessing" title="Permalink to this headline"></a></h1>
<div class="section" id="threading-multiprocessing">
<h2>Threading / multiprocessing<a class="headerlink" href="#threading-multiprocessing" title="Permalink to this headline"></a></h2>
<p>How to actually DO threading and multiprocessing:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">threading</span></code> module</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">multiprocessing</span></code> module</p></li>
</ul>
<p>Parallel programming can be hard!</p>
<p>If your problem can be solved sequentially, consider the costs and
benefits before going parallel.</p>
<div class="section" id="parallelization-strategy-for-performance">
<h3>Parallelization Strategy for Performance<a class="headerlink" href="#parallelization-strategy-for-performance" title="Permalink to this headline"></a></h3>
<div class="line-block">
<div class="line">1. Break problem down into chunks</div>
<div class="line">2. Execute chunks in parallel</div>
<div class="line">3. Reassemble output of chunks into result</div>
</div>
<a class="reference internal image-reference" href="../_images/OPP.0108.gif"><img alt="multitasking flow diagram" class="align-right" src="../_images/OPP.0108.gif" style="height: 450px;" /></a>
<div class="line-block">
<div class="line"><br /></div>
<div class="line"><br /></div>
</div>
<ul class="simple">
<li><p>Not every problem is parallelizable</p></li>
<li><p>There is an optimal number of threads for each problem in each
environment, so make it tunable</p></li>
<li><p>Working concurrently opens up synchronization issues</p></li>
<li><p>Methods for synchronizing threads:</p>
<ul>
<li><p>locks</p></li>
<li><p>queues</p></li>
<li><p>signaling/messaging mechanisms</p></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section" id="the-mechanics-how-do-you-use-threads-and-or-processes">
<h2>The mechanics: how do you use threads and/or processes<a class="headerlink" href="#the-mechanics-how-do-you-use-threads-and-or-processes" title="Permalink to this headline"></a></h2>
<p>Python provides the <cite>threading</cite> and <cite>multiprocessing</cite> modules to facility concurrency.</p>
<p>They have similar APIs – so you can use them in similar ways.</p>
<p>Key points:</p>
<blockquote>
<div><ul class="simple">
<li><p>There is no Python thread scheduler, it is up to the host OS. yes these are “true” threads.</p></li>
<li><p>Works well for I/O bound problems, can use literally thousands of threads</p></li>
<li><p>Limit CPU-bound processing to C extensions (that release the GIL)</p></li>
<li><p>Do not use for CPU bound problems, will go slower than no threads, especially on multiple cores!!! (see David Beazley’s talk referenced above)</p></li>
</ul>
</div></blockquote>
<p>Starting threads is relatively simple, but there are many potential issues.</p>
<p>We already talked about shared data, this can lead to a “race condition”.</p>
<blockquote>
<div><ul class="simple">
<li><p>May produce slightly different results every run</p></li>
<li><p>May just flake out mysteriously every once in a while</p></li>
<li><p>May run fine when testing, but fail when run on:
- a slower system
- a heavily loaded system
- a larger dataset</p></li>
<li><p>Thus you <em>must</em> synchronize threads!</p></li>
</ul>
</div></blockquote>
<div class="section" id="example-a-cpu-bound-problem">
<h3>Example: A CPU bound problem<a class="headerlink" href="#example-a-cpu-bound-problem" title="Permalink to this headline"></a></h3>
<p>Numerically integrate the function
<span class="math notranslate nohighlight">\(y =x^2\)</span> from 0 to 10.</p>
<p><a class="reference external" href="http://www.wolframalpha.com/input/?i=x%5E2">http://www.wolframalpha.com/input/?i=x%5E2</a></p>
<a class="reference internal image-reference" href="../_images/x2.png"><img alt="../_images/x2.png" src="../_images/x2.png" style="height: 400px;" /></a>
<p><a class="reference external" href="http://www.wolframalpha.com/input/?i=int(x%5E2,0,10)">Solution</a></p>
</div>
<div class="section" id="parallel-execution-example">
<h3>Parallel execution example<a class="headerlink" href="#parallel-execution-example" title="Permalink to this headline"></a></h3>
<p>Consider the following code in:
<a class="reference download internal" download="" href="../_downloads/c1cc9b924fb183dcd627bdd88e164621/integrate.py"><code class="xref download docutils literal notranslate"><span class="pre">integrate.py</span></code></a></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span>
<span class="k">def</span> <span class="nf">integrate</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">N</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">dx</span> <span class="o">=</span> <span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span><span class="o">/</span><span class="n">N</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
<span class="n">s</span> <span class="o">+=</span> <span class="n">f</span><span class="p">(</span><span class="n">a</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="n">dx</span><span class="p">)</span>
<span class="k">return</span> <span class="n">s</span> <span class="o">*</span> <span class="n">dx</span>
</pre></div>
</div>
<p>We can do better than this</p>
<p>Break down the problem into parallelizable chunks, then add the results
together:</p>
</div>
<div class="section" id="the-threading-module">
<h3>The threading module<a class="headerlink" href="#the-threading-module" title="Permalink to this headline"></a></h3>
<p>Starting threads doesn’t take much:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">():</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"hello from thread </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">threads</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">3</span><span class="p">):</span>
<span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">func</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">())</span>
<span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">threads</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">thread</span><span class="p">)</span>
</pre></div>
</div>
<ul class="simple">
<li><p>The process will exit when the last non-daemon thread exits.</p></li>
<li><p>A thread can be specified as a daemon thread by setting its daemon
attribute: <code class="docutils literal notranslate"><span class="pre">thread.daemon</span> <span class="pre">=</span> <span class="pre">True</span></code></p></li>
<li><p>daemon threads get cut off at program exit, without any opportunity
for cleanup. But you don’t have to track and manage them. Useful for
things like garbage collection, network keepalives, ..</p></li>
<li><p>You can block and wait for a thread to exit with thread.join()</p></li>
</ul>
</div>
<div class="section" id="subclassing-thread">
<h3>Subclassing Thread<a class="headerlink" href="#subclassing-thread" title="Permalink to this headline"></a></h3>
<p>You can add threading capability to your own classes</p>
<p>Subclass Thread and implement the run method</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span>
<span class="k">class</span> <span class="nc">MyThread</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"hello from </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="n">thread</span> <span class="o">=</span> <span class="n">MyThread</span><span class="p">()</span>
<span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="race-conditions">
<h3>Race Conditions<a class="headerlink" href="#race-conditions" title="Permalink to this headline"></a></h3>
<p>In the last example we saw threads competing for access to stdout.</p>
<p>Worse, if competing threads try to update the same value, we might get
an unexpected race condition</p>
<p>Race conditions occur when multiple statements need to execute
atomically, but get interrupted midway</p>
<p><a class="reference download internal" download="" href="../_downloads/dd35fde1efea7d19ffe17d2f7a3cd0b5/race_condition.py"><code class="xref download docutils literal notranslate"><span class="pre">race_condition.py</span></code></a></p>
</div>
<div class="section" id="no-race-condition">
<h3>No race condition<a class="headerlink" href="#no-race-condition" title="Permalink to this headline"></a></h3>
<table class="docutils align-default">
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Thread 1</p></th>
<th class="head"><p>Thread 2</p></th>
<th class="head"></th>
<th class="head"><p>Integer value</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td></td>
<td></td>
<td></td>
<td><p>0</p></td>
</tr>
<tr class="row-odd"><td><p>read value</p></td>
<td></td>
<td><p>←</p></td>
<td><p>0</p></td>
</tr>
<tr class="row-even"><td><p>increase value</p></td>
<td></td>
<td></td>
<td><p>0</p></td>
</tr>
<tr class="row-odd"><td><p>write back</p></td>
<td></td>
<td><p>→</p></td>
<td><p>1</p></td>
</tr>
<tr class="row-even"><td></td>
<td><p>read value</p></td>
<td><p>←</p></td>
<td><p>1</p></td>
</tr>
<tr class="row-odd"><td></td>
<td><p>increase value</p></td>
<td></td>
<td><p>1</p></td>
</tr>
<tr class="row-even"><td></td>
<td><p>write back</p></td>
<td><p>→</p></td>
<td><p>2</p></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="race-condition">
<h3>Race Condition!<a class="headerlink" href="#race-condition" title="Permalink to this headline"></a></h3>
<table class="docutils align-default">
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Thread 1</p></th>
<th class="head"><p>Thread 2</p></th>
<th class="head"></th>
<th class="head"><p>Integer value</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td></td>
<td></td>
<td></td>
<td><p>0</p></td>
</tr>
<tr class="row-odd"><td><p>read value</p></td>
<td></td>
<td><p>←</p></td>
<td><p>0</p></td>
</tr>
<tr class="row-even"><td></td>
<td><p>read value</p></td>
<td><p>←</p></td>
<td><p>0</p></td>
</tr>
<tr class="row-odd"><td><p>increase value</p></td>
<td></td>
<td></td>
<td><p>0</p></td>
</tr>
<tr class="row-even"><td></td>
<td><p>increase value</p></td>
<td></td>
<td><p>0</p></td>
</tr>
<tr class="row-odd"><td><p>write back</p></td>
<td></td>
<td><p>→</p></td>
<td><p>1</p></td>
</tr>
<tr class="row-even"><td></td>
<td><p>write back</p></td>
<td><p>→</p></td>
<td><p>1</p></td>
</tr>
</tbody>
</table>
<p><a class="reference external" href="http://en.wikipedia.org/wiki/Race_condition">http://en.wikipedia.org/wiki/Race_condition</a></p>
</div>
<div class="section" id="deadlocks">
<h3>Deadlocks<a class="headerlink" href="#deadlocks" title="Permalink to this headline"></a></h3>
<p>Synchronization and Critical Sections are used to control race
conditions</p>
<p>But they introduce other potential problems…</p>
<p>like: <a class="reference external" href="http://en.wikipedia.org/wiki/Deadlock">http://en.wikipedia.org/wiki/Deadlock</a></p>
<p>“A deadlock is a situation in which two or more competing actions are
each waiting for the other to finish, and thus neither ever does.”</p>
<p><em>When two trains approach each other at a crossing, both shall come to a
full stop and neither shall start up again until the other has gone</em></p>
<p>See also <em>Livelock</em>:</p>
<p><em>Two people meet in a narrow corridor, and each
tries to be polite by moving aside to let the other pass, but they end
up swaying from side to side without making any progress because they
both repeatedly move the same way at the same time.</em></p>
</div>
<div class="section" id="locks">
<h3>Locks<a class="headerlink" href="#locks" title="Permalink to this headline"></a></h3>
<p>Lock objects allow threads to control access to a resource until they’re done with it</p>
<p>This is known as mutual exclusion, often called “mutex”.</p>
<p>A Lock has two states: locked and unlocked</p>
<p>If multiple threads have access to the same Lock, they can police
themselves by calling its <code class="docutils literal notranslate"><span class="pre">.acquire()</span></code> and <code class="docutils literal notranslate"><span class="pre">.release()</span></code> methods</p>
<p>If a Lock is locked, .acquire will block until it becomes unlocked</p>
<p>These threads will wait in line politely for access to the statements in f()</p>
</div>
<div class="section" id="mutex-locks-threading-lock">
<h3>Mutex locks (<code class="docutils literal notranslate"><span class="pre">threading.Lock</span></code>)<a class="headerlink" href="#mutex-locks-threading-lock" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>Probably most common</p></li>
<li><p>Only one thread can modify shared data at any given time</p></li>
<li><p>Thread determines when unlocked</p></li>
<li><p>Must put lock/unlock around critical code in ALL threads</p></li>
<li><p>Difficult to manage</p></li>
</ul>
</div></blockquote>
<p>Easiest with context manager:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">x_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
<span class="c1"># Example critical section</span>
<span class="k">with</span> <span class="n">x_lock</span><span class="p">:</span>
<span class="c1"># statements using x</span>
</pre></div>
</div>
<p>Only one lock per thread! (or risk mysterious deadlocks)</p>
<p>Or use RLock for code-based locking (locking function/method execution rather than data access)</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="n">lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2"> got lock"</span> <span class="o">%</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">lock</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">f</span><span class="p">)</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="nonblocking-locking">
<h3>Nonblocking Locking<a class="headerlink" href="#nonblocking-locking" title="Permalink to this headline"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">.acquire()</span></code> will return True if it successfully acquires a lock</p>
<p>Its first argument is a boolean which specifies whether a lock should
block or not. The default is <code class="docutils literal notranslate"><span class="pre">True</span></code></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span>
<span class="n">lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
<span class="n">lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">(</span><span class="kc">False</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"couldn't get lock"</span><span class="p">)</span>
<span class="n">lock</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
<span class="k">if</span> <span class="n">lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">(</span><span class="kc">False</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"got lock"</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="threading-rlock-reentrant-lock">
<h3><code class="docutils literal notranslate"><span class="pre">threading.RLock</span></code> - Reentrant Lock<a class="headerlink" href="#threading-rlock-reentrant-lock" title="Permalink to this headline"></a></h3>
<p>Useful for recursive algorithms, a thread-specific count of the locks is
maintained</p>
<p>A reentrant lock can be acquired multiple times by the same thread</p>
<p><code class="docutils literal notranslate"><span class="pre">Lock.release()</span></code> must be called the same number of times as <code class="docutils literal notranslate"><span class="pre">Lock.acquire()</span></code>
by that thread</p>
</div>
<div class="section" id="threading-semaphore">
<h3><code class="docutils literal notranslate"><span class="pre">threading.Semaphore</span></code><a class="headerlink" href="#threading-semaphore" title="Permalink to this headline"></a></h3>
<p>Like an <code class="docutils literal notranslate"><span class="pre">RLock</span></code>, but in reverse</p>
<p>A Semaphore is given an initial counter value, defaulting to 1</p>
<p>Each call to <code class="docutils literal notranslate"><span class="pre">acquire()</span></code> decrements the counter, <code class="docutils literal notranslate"><span class="pre">release()</span></code> increments it</p>
<p>If <code class="docutils literal notranslate"><span class="pre">acquire()</span></code> is called on a Semaphore with a counter of 0, it will block
until the Semaphore counter is greater than 0.</p>
<p>Useful for controlling the maximum number of threads allowed to access a
resource simultaneously</p>
<p><a class="reference external" href="http://en.wikipedia.org/wiki/Semaphore_(programming)">Semaphore</a></p>
<a class="reference internal image-reference" href="../_images/flags.jpg"><img alt="../_images/flags.jpg" src="../_images/flags.jpg" style="height: 250px;" /></a>
</div>
<div class="section" id="events-threading-event">
<h3>Events (<code class="docutils literal notranslate"><span class="pre">threading.Event</span></code>)<a class="headerlink" href="#events-threading-event" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>Threads can wait for particular event</p></li>
<li><p>Setting an event unblocks all waiting threads</p></li>
</ul>
</div></blockquote>
<p>Common use: barriers, notification</p>
</div>
<div class="section" id="condition-threading-condition">
<h3>Condition (<code class="docutils literal notranslate"><span class="pre">threading.Condition</span></code>)<a class="headerlink" href="#condition-threading-condition" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>Combination of locking/signaling</p></li>
<li><p>lock protects code that establishes a “condition” (e.g., data available)</p></li>
<li><p>signal notifies threads that “condition” has changed</p></li>
</ul>
</div></blockquote>
<p>Common use: producer/consumer patterns</p>
</div>
<div class="section" id="locking-exercise">
<h3>Locking Exercise<a class="headerlink" href="#locking-exercise" title="Permalink to this headline"></a></h3>
<p><a class="reference download internal" download="" href="../_downloads/f08b1501d4508a3350b31cfe284ba554/lock_exercise.zip"><code class="xref download docutils literal notranslate"><span class="pre">lock_exercise.zip</span></code></a></p>
<p>In: <code class="docutils literal notranslate"><span class="pre">lock/stdout_writer.py</span></code></p>
<p>Multiple threads in the script write to stdout, and their output gets
jumbled</p>
<ol class="arabic simple">
<li><p>Add a locking mechanism to give each thread exclusive access to
stdout</p></li>
<li><p>Try adding a Semaphore to allow 2 threads access at once</p></li>
</ol>
</div>
<div class="section" id="managing-thread-results">
<h3>Managing thread results<a class="headerlink" href="#managing-thread-results" title="Permalink to this headline"></a></h3>
<p>We need a thread safe way of storing results from multiple threads of
execution. That is provided by the Queue module.</p>
<p>Queues allow multiple producers and multiple consumers to exchange data
safely</p>
<p>Size of the queue is managed with the maxsize kwarg</p>
<p>It will block consumers if empty and block producers if full</p>
<p>If maxsize is less than or equal to zero, the queue size is infinite</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">Queue</span> <span class="kn">import</span> <span class="n">Queue</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">Queue</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">q</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="mi">37337</span><span class="p">)</span>
<span class="n">block</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">timeout</span> <span class="o">=</span> <span class="mi">2</span>
<span class="nb">print</span><span class="p">(</span><span class="n">q</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="n">timeout</span><span class="p">))</span>
</pre></div>
</div>
<ul class="simple">
<li><p><a class="reference external" href="http://docs.python.org/3/library/threading.html">http://docs.python.org/3/library/threading.html</a></p></li>
<li><p><a class="reference external" href="http://docs.python.org/3/library/queue.html">http://docs.python.org/3/library/queue.html</a></p></li>
</ul>
</div>
<div class="section" id="queues-queue">
<h3>Queues (<code class="docutils literal notranslate"><span class="pre">queue</span></code>)<a class="headerlink" href="#queues-queue" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>Easier to use than many of above</p></li>
<li><p>Do not need locks</p></li>
<li><p>Has signaling</p></li>
</ul>
</div></blockquote>
<p>Common use: producer/consumer patterns</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">Queue</span> <span class="kn">import</span> <span class="n">Queue</span>
<span class="n">data_q</span> <span class="o">=</span> <span class="n">Queue</span><span class="p">()</span>
<span class="n">Producer</span> <span class="n">thread</span><span class="p">:</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">produce_items</span><span class="p">():</span>
<span class="n">data_q</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="n">Consumer</span> <span class="n">thread</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">item</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="n">consume_item</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="scheduling-sched">
<h3>Scheduling (<code class="docutils literal notranslate"><span class="pre">sched</span></code>)<a class="headerlink" href="#scheduling-sched" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>Schedules based on time, either absolute or delay</p></li>
<li><p>Low level, so has many of the traps of the threading synchronization primitives.</p></li>
</ul>
</div></blockquote>
</div>
<div class="section" id="timed-events-threading-timer">
<h3>Timed events (<code class="docutils literal notranslate"><span class="pre">threading.timer</span></code>)<a class="headerlink" href="#timed-events-threading-timer" title="Permalink to this headline"></a></h3>
<p>Run a function at some time in the future:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span>
<span class="k">def</span> <span class="nf">called_once</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> this function is designed to be called once in the future</span>
<span class="sd"> """</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"I just got called! It's now: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">asctime</span><span class="p">()))</span>
<span class="c1"># setting it up to be called</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">Timer</span><span class="p">(</span><span class="n">interval</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">function</span><span class="o">=</span><span class="n">called_once</span><span class="p">)</span>
<span class="n">t</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="c1"># you can cancel it if you want:</span>
<span class="n">t</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference download internal" download="" href="../_downloads/d2f4d19315e96ba42fa214da38e3d8b3/simple_timer.py"><code class="xref download docutils literal notranslate"><span class="pre">simple_timer.py</span></code></a></p>
</div>
<div class="section" id="other-queue-types">
<h3>Other Queue types<a class="headerlink" href="#other-queue-types" title="Permalink to this headline"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">Queue.LifoQueue</span></code></p>
<blockquote>
<div><ul class="simple">
<li><p>Last In, First Out</p></li>
</ul>
</div></blockquote>
<p><code class="docutils literal notranslate"><span class="pre">Queue.PriorityQueue</span></code></p>
<blockquote>
<div><ul class="simple">
<li><p>Lowest valued entries are retrieved first</p></li>
</ul>
</div></blockquote>
<p>One pattern for <code class="docutils literal notranslate"><span class="pre">PriorityQueue</span></code> is to insert entries of form data by
inserting the tuple:</p>
<p><code class="docutils literal notranslate"><span class="pre">(priority_number,</span> <span class="pre">data)</span></code></p>
</div>
<div class="section" id="threading-example-with-a-queue">
<h3>Threading example with a queue<a class="headerlink" href="#threading-example-with-a-queue" title="Permalink to this headline"></a></h3>
<p><a class="reference download internal" download="" href="../_downloads/b8e9fa621bddde6623aa18c3db828f62/integrate_threads.py"><code class="xref download docutils literal notranslate"><span class="pre">integrate_main.py</span></code></a></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">queue</span>
<span class="c1"># from integrate.integrate import integrate, f</span>
<span class="kn">from</span> <span class="nn">integrate</span> <span class="kn">import</span> <span class="n">f</span><span class="p">,</span> <span class="n">integrate_numpy</span> <span class="k">as</span> <span class="n">integrate</span>
<span class="kn">from</span> <span class="nn">decorators</span> <span class="kn">import</span> <span class="n">timer</span>
<span class="nd">@timer</span>
<span class="k">def</span> <span class="nf">threading_integrate</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">thread_count</span><span class="o">=</span><span class="mi">2</span><span class="p">):</span>
<span class="sd">"""break work into N chunks"""</span>
<span class="n">N_chunk</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">N</span><span class="p">)</span> <span class="o">/</span> <span class="n">thread_count</span><span class="p">)</span>
<span class="n">dx</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">b</span> <span class="o">-</span> <span class="n">a</span><span class="p">)</span> <span class="o">/</span> <span class="n">thread_count</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">Queue</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">worker</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="n">results</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">integrate</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">))</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">thread_count</span><span class="p">):</span>
<span class="n">x0</span> <span class="o">=</span> <span class="n">dx</span> <span class="o">*</span> <span class="n">i</span>
<span class="n">x1</span> <span class="o">=</span> <span class="n">x0</span> <span class="o">+</span> <span class="n">dx</span>
<span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">worker</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">x1</span><span class="p">,</span> <span class="n">N_chunk</span><span class="p">))</span>
<span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Thread </span><span class="si">%s</span><span class="s2"> started"</span> <span class="o">%</span> <span class="n">thread</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">sum</span><span class="p">((</span><span class="n">results</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">thread_count</span><span class="p">)))</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="c1"># parameters of the integration</span>
<span class="n">a</span> <span class="o">=</span> <span class="mf">0.0</span>
<span class="n">b</span> <span class="o">=</span> <span class="mf">10.0</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">10</span><span class="o">**</span><span class="mi">8</span>
<span class="n">thread_count</span> <span class="o">=</span> <span class="mi">8</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Numerical solution with N=</span><span class="si">%(N)d</span><span class="s2"> : </span><span class="si">%(x)f</span><span class="s2">"</span> <span class="o">%</span>
<span class="p">{</span><span class="s1">'N'</span><span class="p">:</span> <span class="n">N</span><span class="p">,</span> <span class="s1">'x'</span><span class="p">:</span> <span class="n">threading_integrate</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">thread_count</span><span class="o">=</span><span class="n">thread_count</span><span class="p">)})</span>
</pre></div>
</div>
</div>
<div class="section" id="threading-on-a-cpu-bound-problem">
<h3>Threading on a CPU bound problem<a class="headerlink" href="#threading-on-a-cpu-bound-problem" title="Permalink to this headline"></a></h3>
<p>Try running the code in <a class="reference download internal" download="" href="../_downloads/b8e9fa621bddde6623aa18c3db828f62/integrate_threads.py"><code class="xref download docutils literal notranslate"><span class="pre">integrate_threads.py</span></code></a></p>
<p>It has a couple of tunable parameters:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="mf">0.0</span> <span class="c1"># the start of the integration</span>
<span class="n">b</span> <span class="o">=</span> <span class="mf">10.0</span> <span class="c1"># the end point of the integration</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">10</span><span class="o">**</span><span class="mi">8</span> <span class="c1"># the number of steps to use in the integration</span>
<span class="n">thread_count</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># the number of threads to use</span>
</pre></div>
</div>
<p>What happens when you change the thread count? What thread count gives the maximum speed?</p>
</div>
<div class="section" id="multiprocessing">
<h3>Multiprocessing<a class="headerlink" href="#multiprocessing" title="Permalink to this headline"></a></h3>
<blockquote>
<div><ul class="simple">
<li><p>processes are completely isolated</p></li>
<li><p>no locking :) (and no GIL!)</p></li>
<li><p>instead of locking: messaging</p></li>
</ul>
</div></blockquote>
<p><code class="docutils literal notranslate"><span class="pre">multiprocessing</span></code> provides an API very similar to <code class="docutils literal notranslate"><span class="pre">threading</span></code>, so the transition is easy</p>
<p>use <code class="docutils literal notranslate"><span class="pre">multiprocessing.Process</span></code> instead of <code class="docutils literal notranslate"><span class="pre">threading.Thread</span></code></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">multiprocessing</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">():</span>
<span class="nb">print</span> <span class="s2">"hello from process </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">multiprocessing</span><span class="o">.</span><span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">func</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">())</span>
<span class="n">proc</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">multiprocessing</span><span class="o">.</span><span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">func</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">())</span>
<span class="n">proc</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="differences-with-threading">
<h3>Differences with Threading<a class="headerlink" href="#differences-with-threading" title="Permalink to this headline"></a></h3>
<p>Multiprocessing has its own <code class="docutils literal notranslate"><span class="pre">multiprocessing.Queue</span></code> which handles
interprocess communication</p>
<p>Also has its own versions of <code class="docutils literal notranslate"><span class="pre">Lock</span></code>, <code class="docutils literal notranslate"><span class="pre">RLock</span></code>, <code class="docutils literal notranslate"><span class="pre">Semaphore</span></code></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Queue</span><span class="p">,</span> <span class="n">Lock</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">multiprocessing.Pipe</span></code> for 2-way process communication:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Pipe</span>
<span class="n">parent_conn</span><span class="p">,</span> <span class="n">child_conn</span> <span class="o">=</span> <span class="n">Pipe</span><span class="p">()</span>
<span class="n">child_conn</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">parent_conn</span><span class="o">.</span><span class="n">recv</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="messaging">
<h3>Messaging<a class="headerlink" href="#messaging" title="Permalink to this headline"></a></h3>
<div class="section" id="pipes-multiprocessing-pipe">
<h4>Pipes (<code class="docutils literal notranslate"><span class="pre">multiprocessing.Pipe</span></code>)<a class="headerlink" href="#pipes-multiprocessing-pipe" title="Permalink to this headline"></a></h4>
<blockquote>
<div><ul class="simple">
<li><p>Returns a pair of connected objects</p></li>
<li><p>Largely mimics Unix pipes, but higher level</p></li>
<li><p>send pickled objects or buffers</p></li>
</ul>
</div></blockquote>
</div>
<div class="section" id="queues-multiprocessing-queue">
<h4>Queues (<code class="docutils literal notranslate"><span class="pre">multiprocessing.Queue</span></code>)<a class="headerlink" href="#queues-multiprocessing-queue" title="Permalink to this headline"></a></h4>
<blockquote>
<div><ul class="simple">
<li><p>same interface as <code class="docutils literal notranslate"><span class="pre">queue.Queue</span></code></p></li>
<li><p>implemented on top of pipes</p></li>
<li><p>means you can pretty easily port threaded programs using queues to multiprocessing
- queue is the only shared data
- data is all pickled and unpickled to pass between processes – significant overhead.</p></li>
</ul>
</div></blockquote>
</div>
<div class="section" id="other-features-of-the-multiprocessing-package">
<h4>Other features of the multiprocessing package<a class="headerlink" href="#other-features-of-the-multiprocessing-package" title="Permalink to this headline"></a></h4>
<blockquote>
<div><ul class="simple">
<li><p>Pools</p></li>
<li><p>Shared objects and arrays</p></li>
<li><p>Synchronization primitives</p></li>
<li><p>Managed objects</p></li>
<li><p>Connections</p></li>
</ul>
</div></blockquote>
</div>
</div>
<div class="section" id="pooling">
<h3>Pooling<a class="headerlink" href="#pooling" title="Permalink to this headline"></a></h3>
<p>A processing pool contains worker processes with only a configured
number running at one time</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Pool</span>
<span class="n">pool</span> <span class="o">=</span> <span class="n">Pool</span><span class="p">(</span><span class="n">processes</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>The Pool module has several methods for adding jobs to the pool</p>
<p><code class="docutils literal notranslate"><span class="pre">apply_async(func[,</span> <span class="pre">args[,</span> <span class="pre">kwargs[,</span> <span class="pre">callback]]])</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">map_async(func,</span> <span class="pre">iterable[,</span> <span class="pre">chunksize[,</span> <span class="pre">callback]])</span></code></p>
</div>
<div class="section" id="pooling-example">
<h3>Pooling example<a class="headerlink" href="#pooling-example" title="Permalink to this headline"></a></h3>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Pool</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span><span class="o">*</span><span class="n">x</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">pool</span> <span class="o">=</span> <span class="n">Pool</span><span class="p">(</span><span class="n">processes</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">apply_async</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="p">(</span><span class="mi">10</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">pool</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)))</span>
<span class="n">it</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">imap</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">next</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">next</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">next</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">apply_async</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">,</span> <span class="p">(</span><span class="mi">10</span><span class="p">,))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<p><a class="reference external" href="http://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool">http://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool</a></p>
</div>
<div class="section" id="threadpool">
<h3>ThreadPool<a class="headerlink" href="#threadpool" title="Permalink to this headline"></a></h3>
<p>Threading also has a pool</p>
<p>Confusingly, it lives in the multiprocessing module</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">multiprocessing.pool</span> <span class="kn">import</span> <span class="n">ThreadPool</span>
<span class="n">pool</span> <span class="o">=</span> <span class="n">ThreadPool</span><span class="p">(</span><span class="n">processes</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="Coroutines.html" class="btn btn-neutral float-left" title="Notes on Coroutines" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../exercises/threaded_downloader.html" class="btn btn-neutral float-right" title="Threaded Web Scraper" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2020, University of Washington, Natasha Aleksandrova, Christopher Barker, Brian Dorsey, Cris Ewing, Christy Heaton, Jon Jacky, Maria McKinley, Andy Miles, Rick Riehle, Joseph Schilz, Joseph Sheedy, Hosung Song. Creative Commons Attribution-ShareAlike 4.0 license.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>