~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/threading.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Using Threads in Twisted</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Using Threads in Twisted</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Running code in a thread-safe manner</a></li><li><a href="#auto1">Running code in threads</a></li><li><a href="#auto2">Utility Methods</a></li><li><a href="#auto3">Managing the Thread Pool</a></li></ol></div>
 
10
    <div class="content">
 
11
    <span/>
 
12
 
 
13
    <h2>Running code in a thread-safe manner<a name="auto0"/></h2>
 
14
 
 
15
    <p>Most code in Twisted is not thread-safe. For example,
 
16
    writing data to a transport from a protocol is not thread-safe.
 
17
    Therefore, we want a way to schedule methods to be run in the
 
18
    main event loop. This can be done using the function <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorThreads.callFromThread.html" title="twisted.internet.interfaces.IReactorThreads.callFromThread">twisted.internet.interfaces.IReactorThreads.callFromThread</a></code>:</p>
 
19
<pre class="python"><p class="py-linenumber"> 1
 
20
 2
 
21
 3
 
22
 4
 
23
 5
 
24
 6
 
25
 7
 
26
 8
 
27
 9
 
28
10
 
29
11
 
30
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
31
 
 
32
<span class="py-src-keyword">def</span> <span class="py-src-identifier">notThreadSafe</span>(<span class="py-src-parameter">x</span>):
 
33
     <span class="py-src-string">&quot;&quot;&quot;do something that isn't thread-safe&quot;&quot;&quot;</span>
 
34
     <span class="py-src-comment"># ...</span>
 
35
 
 
36
<span class="py-src-keyword">def</span> <span class="py-src-identifier">threadSafeScheduler</span>():
 
37
    <span class="py-src-string">&quot;&quot;&quot;Run in thread-safe manner.&quot;&quot;&quot;</span>
 
38
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callFromThread</span>(<span class="py-src-variable">notThreadSafe</span>, <span class="py-src-number">3</span>) <span class="py-src-comment"># will run 'notThreadSafe(3)'</span>
 
39
                                             <span class="py-src-comment"># in the event loop</span>
 
40
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
41
</pre>
 
42
 
 
43
    <h2>Running code in threads<a name="auto1"/></h2>
 
44
 
 
45
    <p>Sometimes we may want to run methods in threads - for
 
46
    example, in order to access blocking APIs. Twisted provides
 
47
    methods for doing so using the IReactorThreads API (<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorThreads.html" title="twisted.internet.interfaces.IReactorThreads">twisted.internet.interfaces.IReactorThreads</a></code>).
 
48
    Additional utility functions are provided in <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.threads.html" title="twisted.internet.threads">twisted.internet.threads</a></code>. Basically, these
 
49
    methods allow us to queue methods to be run by a thread
 
50
    pool.</p>
 
51
 
 
52
    <p>For example, to run a method in a thread we can do:</p>
 
53
<pre class="python"><p class="py-linenumber"> 1
 
54
 2
 
55
 3
 
56
 4
 
57
 5
 
58
 6
 
59
 7
 
60
 8
 
61
 9
 
62
10
 
63
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
64
 
 
65
<span class="py-src-keyword">def</span> <span class="py-src-identifier">aSillyBlockingMethod</span>(<span class="py-src-parameter">x</span>):
 
66
    <span class="py-src-keyword">import</span> <span class="py-src-variable">time</span>
 
67
    <span class="py-src-variable">time</span>.<span class="py-src-variable">sleep</span>(<span class="py-src-number">2</span>)
 
68
    <span class="py-src-keyword">print</span> <span class="py-src-variable">x</span>
 
69
 
 
70
<span class="py-src-comment"># run method in thread</span>
 
71
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">callInThread</span>(<span class="py-src-variable">aSillyBlockingMethod</span>, <span class="py-src-string">&quot;2 seconds have passed&quot;</span>)
 
72
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
73
</pre>
 
74
 
 
75
    <h2>Utility Methods<a name="auto2"/></h2>
 
76
 
 
77
    <p>The utility methods are not part of the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.reactor.html" title="twisted.internet.reactor">twisted.internet.reactor</a></code> APIs, but are implemented
 
78
    in <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.threads.html" title="twisted.internet.threads">twisted.internet.threads</a></code>.</p>
 
79
 
 
80
    <p>If we have multiple methods to run sequentially within a thread,
 
81
    we can do:</p>
 
82
 
 
83
<pre class="python"><p class="py-linenumber"> 1
 
84
 2
 
85
 3
 
86
 4
 
87
 5
 
88
 6
 
89
 7
 
90
 8
 
91
 9
 
92
10
 
93
11
 
94
12
 
95
13
 
96
14
 
97
15
 
98
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>, <span class="py-src-variable">threads</span>
 
99
 
 
100
<span class="py-src-keyword">def</span> <span class="py-src-identifier">aSillyBlockingMethodOne</span>(<span class="py-src-parameter">x</span>):
 
101
    <span class="py-src-keyword">import</span> <span class="py-src-variable">time</span>
 
102
    <span class="py-src-variable">time</span>.<span class="py-src-variable">sleep</span>(<span class="py-src-number">2</span>)
 
103
    <span class="py-src-keyword">print</span> <span class="py-src-variable">x</span>
 
104
 
 
105
<span class="py-src-keyword">def</span> <span class="py-src-identifier">aSillyBlockingMethodTwo</span>(<span class="py-src-parameter">x</span>):
 
106
    <span class="py-src-keyword">print</span> <span class="py-src-variable">x</span>
 
107
 
 
108
<span class="py-src-comment"># run both methods sequentially in a thread</span>
 
109
<span class="py-src-variable">commands</span> = [(<span class="py-src-variable">aSillyBlockingMethodOne</span>, [<span class="py-src-string">&quot;Calling First&quot;</span>], {})]
 
110
<span class="py-src-variable">commands</span>.<span class="py-src-variable">append</span>((<span class="py-src-variable">aSillyBlockingMethodTwo</span>, [<span class="py-src-string">&quot;And the second&quot;</span>], {}))
 
111
<span class="py-src-variable">threads</span>.<span class="py-src-variable">callMultipleInThread</span>(<span class="py-src-variable">commands</span>)
 
112
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
113
</pre>
 
114
 
 
115
    <p>For functions whose results we wish to get, we can have the
 
116
    result returned as a Deferred:</p>
 
117
<pre class="python"><p class="py-linenumber"> 1
 
118
 2
 
119
 3
 
120
 4
 
121
 5
 
122
 6
 
123
 7
 
124
 8
 
125
 9
 
126
10
 
127
11
 
128
12
 
129
13
 
130
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>, <span class="py-src-variable">threads</span>
 
131
 
 
132
<span class="py-src-keyword">def</span> <span class="py-src-identifier">doLongCalculation</span>():
 
133
    <span class="py-src-comment"># .... do long calculation here ...</span>
 
134
    <span class="py-src-keyword">return</span> <span class="py-src-number">3</span>
 
135
 
 
136
<span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">x</span>):
 
137
    <span class="py-src-keyword">print</span> <span class="py-src-variable">x</span>
 
138
 
 
139
<span class="py-src-comment"># run method in thread and get result as defer.Deferred</span>
 
140
<span class="py-src-variable">d</span> = <span class="py-src-variable">threads</span>.<span class="py-src-variable">deferToThread</span>(<span class="py-src-variable">doLongCalculation</span>)
 
141
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>)
 
142
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
143
</pre>
 
144
 
 
145
    <p>If you wish to call a method in the reactor thread and get its result,
 
146
    you can use <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.threads.blockingCallFromThread.html" title="twisted.internet.threads.blockingCallFromThread">blockingCallFromThread</a></code>:</p>
 
147
 
 
148
<pre class="python"><p class="py-linenumber"> 1
 
149
 2
 
150
 3
 
151
 4
 
152
 5
 
153
 6
 
154
 7
 
155
 8
 
156
 9
 
157
10
 
158
11
 
159
12
 
160
13
 
161
14
 
162
15
 
163
16
 
164
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">threads</span>, <span class="py-src-variable">reactor</span>, <span class="py-src-variable">defer</span>
 
165
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">client</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">getPage</span>
 
166
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">error</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Error</span>
 
167
 
 
168
<span class="py-src-keyword">def</span> <span class="py-src-identifier">inThread</span>():
 
169
    <span class="py-src-keyword">try</span>:
 
170
        <span class="py-src-variable">result</span> = <span class="py-src-variable">threads</span>.<span class="py-src-variable">blockingCallFromThread</span>(
 
171
            <span class="py-src-variable">reactor</span>, <span class="py-src-variable">getPage</span>, <span class="py-src-string">&quot;http://twistedmatrix.com/&quot;</span>)
 
172
    <span class="py-src-keyword">except</span> <span class="py-src-variable">Error</span>, <span class="py-src-variable">exc</span>:
 
173
        <span class="py-src-keyword">print</span> <span class="py-src-variable">exc</span>
 
174
    <span class="py-src-keyword">else</span>:
 
175
        <span class="py-src-keyword">print</span> <span class="py-src-variable">result</span>
 
176
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callFromThread</span>(<span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>)
 
177
 
 
178
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">callInThread</span>(<span class="py-src-variable">inThread</span>)
 
179
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
180
</pre>
 
181
 
 
182
    <p><code>blockingCallFromThread</code> will return the object or raise
 
183
    the exception returned or raised by the function passed to it. If the
 
184
    function passed to it returns a Deferred, it will return the value the
 
185
    Deferred is called back with or raise the exception it is errbacked
 
186
    with.</p>
 
187
 
 
188
    <h2>Managing the Thread Pool<a name="auto3"/></h2>
 
189
 
 
190
    <p>The thread pool is implemented by <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.threadpool.ThreadPool.html" title="twisted.python.threadpool.ThreadPool">twisted.python.threadpool.ThreadPool</a></code>.</p>
 
191
 
 
192
    <p>We may want to modify the size of the threadpool, increasing
 
193
    or decreasing the number of threads in use.  We can do this
 
194
    do this quite easily:</p>
 
195
 
 
196
<pre class="python"><p class="py-linenumber">1
 
197
2
 
198
3
 
199
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
200
 
 
201
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">suggestThreadPoolSize</span>(<span class="py-src-number">30</span>)
 
202
</pre>
 
203
 
 
204
  <p>The default size of the thread pool depends on the reactor being used;
 
205
  the default reactor uses a minimum size of 5 and a maximum size of 10.  Be
 
206
  careful that you understand threads and their resource usage before
 
207
  drastically altering the thread pool sizes.</p>
 
208
  </div>
 
209
 
 
210
    <p><a href="index.html">Index</a></p>
 
211
    <span class="version">Version: 10.0.0</span>
 
212
  </body>
 
213
</html>
 
 
b'\\ No newline at end of file'