Merge branch 'tleonhardt-python_threads'

* tleonhardt-python_threads:
  Style fixes for Python threads documentation changes
  Finished updating Python docs for -threads option
  Started making changes to Python.html to document support for multithreaded Python SWIG applications.
This commit is contained in:
William S Fulton 2017-03-24 08:22:51 +00:00
commit f0f2fd2dae
2 changed files with 198 additions and 87 deletions

View file

@ -1614,6 +1614,11 @@
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
</ul>
<li><a href="Python.html#Python_multithreaded">Support for Multithreaded Applications</a>
<ul>
<li><a href="Python.html#Python_thread_UI">UI for Enabling Multithreading Support</a>
<li><a href="Python.html#Python_thread_performance">Multithread Performance</a>
</ul>
</ul>
</div>
<!-- INDEX -->

View file

@ -133,6 +133,11 @@
<li><a href="#Python_nn77">Byte string output conversion</a>
<li><a href="#Python_2_unicode">Python 2 Unicode</a>
</ul>
<li><a href="#Python_multithreaded">Support for Multithreaded Applications</a>
<ul>
<li><a href="#Python_thread_UI">UI for Enabling Multithreading Support</a>
<li><a href="#Python_thread_performance">Multithread Performance</a>
</ul>
</ul>
</div>
<!-- INDEX -->
@ -162,7 +167,7 @@ Basics</a>" chapter.
<p>
To build Python extension modules, SWIG uses a layered approach in which
parts of the extension module are defined in C and other parts are
parts of the extension module are defined in C and other parts are
defined in Python. The C layer contains low-level wrappers whereas Python code
is used to define high-level features.
</p>
@ -395,9 +400,9 @@ $ gcc -shared example.o example_wrap.o -o _example.so
</pre></div>
<p>
The exact commands for doing this vary from platform to platform.
However, SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt>
The exact commands for doing this vary from platform to platform.
However, SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt>
directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also
check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
@ -409,7 +414,7 @@ When linking the module, <b>the name of the output file has to match the name
of the module prefixed by an underscore</b>. If the name of your module is "<tt>example</tt>", then the
name of the corresponding object file should be
"<tt>_example.so</tt>" or "<tt>_examplemodule.so</tt>".
The name of the module is specified using the <tt>%module</tt> directive or the
The name of the module is specified using the <tt>%module</tt> directive or the
<tt>-module</tt> command line option.
</p>
@ -433,7 +438,7 @@ An alternative approach to dynamic linking is to rebuild the Python
interpreter with your extension module added to it. In the past,
this approach was sometimes necessary due to limitations in dynamic loading
support on certain machines. However, the situation has improved greatly
over the last few years and you should not consider this approach
over the last few years and you should not consider this approach
unless there is really no other option.
</p>
@ -493,7 +498,7 @@ linking if possible. Some programmers may be inclined
to use static linking in the interest of getting better performance.
However, the performance gained by static linking tends to be rather
minimal in most situations (and quite frankly not worth the extra
hassle in the opinion of this author).
hassle in the opinion of this author).
</p>
<p>
@ -552,13 +557,13 @@ Another possible error is the following:
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
ImportError: dynamic module does not define init function (init_example)
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre>
</div>
<p>
This error is almost always caused when a bad name is given to the shared object file.
For example, if you created a file <tt>example.so</tt> instead of <tt>_example.so</tt> you would
This error is almost always caused when a bad name is given to the shared object file.
For example, if you created a file <tt>example.so</tt> instead of <tt>_example.so</tt> you would
get this error. Alternatively, this error could arise if the name of the module is
inconsistent with the module name supplied with the <tt>%module</tt> directive.
Double-check the interface to make sure the module name and the shared object
@ -584,7 +589,7 @@ This error usually indicates that you forgot to include some object
files or libraries in the linking of the shared library file. Make
sure you compile both the SWIG wrapper file and your original program
into a shared library file. Make sure you pass all of the required libraries
to the linker.
to the linker.
</p>
<p>
@ -619,7 +624,7 @@ problem when you try to use your module:
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
ImportError: libfoo.so: cannot open shared object file: No such file or directory
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre>
</div>
@ -642,7 +647,7 @@ $ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
<p>
Alternatively, you can set the <tt>LD_LIBRARY_PATH</tt> environment variable to
include the directory with your shared libraries.
include the directory with your shared libraries.
If setting <tt>LD_LIBRARY_PATH</tt>, be aware that setting this variable can introduce
a noticeable performance impact on all other applications that you run.
To set it only for Python, you might want to do this instead:
@ -707,7 +712,7 @@ $ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun
</pre></div>
<p>
Of course, the extra libraries to use are completely non-portable---you will
Of course, the extra libraries to use are completely non-portable---you will
probably need to do some experimentation.
</p>
@ -715,8 +720,8 @@ probably need to do some experimentation.
Sometimes people have suggested that it is necessary to relink the
Python interpreter using the C++ compiler to make C++ extension modules work.
In the experience of this author, this has never actually appeared to be
necessary. Relinking the interpreter with C++ really only includes the
special run-time libraries described above---as long as you link your extension
necessary. Relinking the interpreter with C++ really only includes the
special run-time libraries described above---as long as you link your extension
modules with these libraries, it should not be necessary to rebuild Python.
</p>
@ -760,7 +765,7 @@ might want to investigate using a more formal standard such as COM.
On platforms that support 64-bit applications (Solaris, Irix, etc.),
special care is required when building extension modules. On these
machines, 64-bit applications are compiled and linked using a different
set of compiler/linker options. In addition, it is not generally possible to mix
set of compiler/linker options. In addition, it is not generally possible to mix
32-bit and 64-bit code together in the same application.
</p>
@ -814,10 +819,10 @@ If you need to build it on your own, the following notes are provided:
</p>
<p>
You will need to create a DLL that can be loaded into the interpreter.
You will need to create a DLL that can be loaded into the interpreter.
This section briefly describes the use of SWIG with Microsoft Visual
C++. As a starting point, many of SWIG's examples include project
files (.dsp files) for Visual C++ 6. These can be opened by more
files (.dsp files) for Visual C++ 6. These can be opened by more
recent versions of Visual Studio.
You might want to take a quick look at these examples in addition to
reading this section.
@ -852,7 +857,7 @@ settings, select the "Custom Build" option.
"C++:Preprocessor". Add the include directories for your Python
installation under "Additional include directories".
<li>Define the symbol __WIN32__ under preprocessor options.
<li>Define the symbol __WIN32__ under preprocessor options.
<li>Finally, select the settings for the entire project and go to
"Link Options". Add the Python library file to your link libraries.
@ -866,7 +871,7 @@ match the name of your Python module, ie. _example.pyd - Note that _example.dll
If all went well, SWIG will be automatically invoked whenever
you build your project. Any changes made to the interface file will
result in SWIG being automatically executed to produce a new version of
the wrapper file.
the wrapper file.
</p>
<p>
@ -885,9 +890,9 @@ $ python
<p>
If you get an <tt>ImportError</tt> exception when importing the module, you may
have forgotten to include additional library files when you built your module.
If you get an access violation or some kind of general protection fault
immediately upon import, you have a more serious problem. This
is often caused by linking your extension module against the wrong
If you get an access violation or some kind of general protection fault
immediately upon import, you have a more serious problem. This
is often caused by linking your extension module against the wrong
set of Win32 debug or thread libraries. You will have to fiddle around with
the build options of project to try and track this down.
</p>
@ -938,7 +943,7 @@ wrapped into a Python '<tt>example</tt>' module. Underneath the covers,
this module consists of a Python source file <tt>example.py</tt> and a low-level
extension module <tt>_example.so</tt>. When choosing a
module name, make sure you don't use the same name as a built-in
Python command or standard module name.
Python command or standard module name.
</p>
<H3><a name="Python_nn15">36.3.2 Functions</a></H3>
@ -991,8 +996,8 @@ then "a" and "b" are both names for the object containing the value
3.4. Thus, there is only one object containing 3.4 and "a"
and "b" are both names that refer to it. This is quite
different than C where a variable name refers to a memory location in which
a value is stored (and assignment copies data into that location).
Because of this, there is no direct way to map variable
a value is stored (and assignment copies data into that location).
Because of this, there is no direct way to map variable
assignment in C to variable assignment in Python.
</p>
@ -1038,7 +1043,7 @@ error message. For example:
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
TypeError: C variable 'density (double )'
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre></div>
<p>
@ -1188,7 +1193,7 @@ simply represented as opaque values using an especial python container object:
<p>
This pointer value can be freely passed around to different C functions that
expect to receive an object of type <tt>FILE *</tt>. The only thing you can't do is
expect to receive an object of type <tt>FILE *</tt>. The only thing you can't do is
dereference the pointer from Python. Of course, that isn't much of a concern in this example.
</p>
@ -1309,7 +1314,7 @@ is used as follows:
&gt;&gt;&gt; v.y = 7.2
&gt;&gt;&gt; print v.x, v.y, v.z
7.8 -4.5 0.0
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre></div>
<p>
@ -1368,7 +1373,7 @@ struct Foo {
<p>
When <tt>char *</tt> members of a structure are wrapped, the contents are assumed to be
dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending on whether or not
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
released and a new value created. If this is not the behavior you want, you will have to use
a typemap (described later).
</p>
@ -1395,7 +1400,7 @@ If accessed in Python, you will see behavior like this:
&gt;&gt;&gt; b = example.Bar()
&gt;&gt;&gt; print b.x
_801861a4_p_int
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre>
</div>
@ -1460,7 +1465,7 @@ Foo *x = &amp;b-&gt;f; /* Points inside b */
</div>
<p>
Because the pointer points inside the structure, you can modify the contents and
Because the pointer points inside the structure, you can modify the contents and
everything works just like you would expect. For example:
</p>
@ -1468,7 +1473,7 @@ everything works just like you would expect. For example:
<pre>
&gt;&gt;&gt; b = Bar()
&gt;&gt;&gt; b.f.a = 3 # Modify attribute of structure member
&gt;&gt;&gt; x = b.f
&gt;&gt;&gt; x = b.f
&gt;&gt;&gt; x.a = 3 # Modifies the same structure
</pre>
</div>
@ -1510,13 +1515,13 @@ you can use it in Python like this:
</pre></div>
<p>
Class data members are accessed in the same manner as C structures.
Class data members are accessed in the same manner as C structures.
</p>
<p>
Static class members present a special problem for Python. Prior to Python-2.2,
Static class members present a special problem for Python. Prior to Python-2.2,
Python classes had no support for static methods and no version of Python
supports static member variables in a manner that SWIG can utilize. Therefore,
supports static member variables in a manner that SWIG can utilize. Therefore,
SWIG generates wrappers that try to work around some of these issues. To illustrate,
suppose you have a class like this:
</p>
@ -1669,10 +1674,10 @@ const Foo &amp;spam9();
<p>
then all three functions will return a pointer to some <tt>Foo</tt> object.
Since the third function (spam8) returns a value, newly allocated memory is used
to hold the result and a pointer is returned (Python will release this memory
Since the third function (spam8) returns a value, newly allocated memory is used
to hold the result and a pointer is returned (Python will release this memory
when the return value is garbage collected). The fourth case (spam9)
which returns a const reference, in most of the cases will be
which returns a const reference, in most of the cases will be
treated as a returning value, and it will follow the same
allocation/deallocation process.
</p>
@ -1771,7 +1776,7 @@ To fix this, you either need to ignore or rename one of the methods. For exampl
<pre>
%rename(spam_short) spam(short);
...
void spam(int);
void spam(int);
void spam(short); // Accessed as spam_short
</pre>
</div>
@ -1784,7 +1789,7 @@ or
<pre>
%ignore spam(short);
...
void spam(int);
void spam(int);
void spam(short); // Ignored
</pre>
</div>
@ -1797,7 +1802,7 @@ first declaration takes precedence.
</p>
<p>
Please refer to the "SWIG and C++" chapter for more information about overloading.
Please refer to the "SWIG and C++" chapter for more information about overloading.
</p>
<H3><a name="Python_nn24">36.3.11 C++ operators</a></H3>
@ -1823,7 +1828,7 @@ public:
Complex operator-(const Complex &amp;c) const;
Complex operator*(const Complex &amp;c) const;
Complex operator-() const;
double re() const { return rpart; }
double im() const { return ipart; }
};
@ -2005,7 +2010,7 @@ In Python:
<p>
Obviously, there is more to template wrapping than shown in this example.
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.
Some more complicated
examples will appear later.
</p>
@ -2188,7 +2193,7 @@ These wrappers can be found in the low-level extension module (e.g., <tt>_exampl
</p>
<p>
Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown
Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown
for Python 2.2):
</p>
@ -2210,7 +2215,7 @@ class Foo(object):
</div>
<p>
This class merely holds a pointer to the underlying C++ object (<tt>.this</tt>) and dispatches methods and
This class merely holds a pointer to the underlying C++ object (<tt>.this</tt>) and dispatches methods and
member variable access to that object using the low-level accessor functions. From a user's point of
view, it makes the class work normally:
</p>
@ -2254,7 +2259,7 @@ class Foo(object):
</div>
<p>When a <tt>Foo</tt> instance is created, the call to <tt>_example.new_Foo()</tt>
creates a new C++ <tt>Foo</tt> instance; wraps that C++ instance inside an instance of
creates a new C++ <tt>Foo</tt> instance; wraps that C++ instance inside an instance of
a python built-in type called <tt>SwigPyObject</tt>; and stores the <tt>SwigPyObject</tt>
instance in the 'this' field of the python Foo object. Did you get all that? So, the
python <tt>Foo</tt> object is composed of three parts:</p>
@ -2545,7 +2550,7 @@ public:
</div>
<p>
If you examine the generated code, the supplied hash function will now be
If you examine the generated code, the supplied hash function will now be
the function callback in the tp_hash slot for the builtin type for <tt>MyClass</tt>:
</p>
@ -2609,7 +2614,7 @@ when the <tt>-builtin</tt> option is used.</p>
<p>
Associated with proxy object, is an ownership flag <tt>.thisown</tt> The value of this
flag determines who is responsible for deleting the underlying C++ object. If set to 1,
the Python interpreter will destroy the C++ object when the proxy class is
the Python interpreter will destroy the C++ object when the proxy class is
garbage collected. If set to 0 (or if the attribute is missing), then the destruction
of the proxy class has no effect on the C++ object.
</p>
@ -2712,7 +2717,7 @@ is assigned to a global variable. For example:
&gt;&gt;&gt; f = example.Foo()
&gt;&gt;&gt; f.thisown
1
&gt;&gt;&gt; example.cvar.head = f
&gt;&gt;&gt; example.cvar.head = f
&gt;&gt;&gt; f.thisown
0
&gt;&gt;&gt;
@ -2813,7 +2818,7 @@ To address differences between Python versions, SWIG currently emits
dual-mode proxy class wrappers. In Python-2.2 and newer releases,
these wrappers encapsulate C++ objects in new-style classes that take
advantage of new features (static methods and properties). However,
if these very same wrappers are imported into an older version of Python,
if these very same wrappers are imported into an older version of Python,
old-style classes are used instead.
</p>
@ -2883,18 +2888,18 @@ option to the %module directive, like this:
<p>
Without this option no director code will be generated. Second, you
must use the %feature("director") directive to tell SWIG which classes
and methods should get directors. The %feature directive can be applied
must use the %feature("director") directive to tell SWIG which classes
and methods should get directors. The %feature directive can be applied
globally, to specific classes, and to specific methods, like this:
</p>
<div class="code">
<pre>
// generate directors for all classes that have virtual methods
%feature("director");
%feature("director");
// generate directors for all virtual methods in class Foo
%feature("director") Foo;
%feature("director") Foo;
</pre>
</div>
@ -2912,11 +2917,11 @@ directors for specific classes or methods. So for example,
<p>
will generate directors for all virtual methods of class Foo except
bar().
bar().
</p>
<p>
Directors can also be generated implicitly through inheritance.
Directors can also be generated implicitly through inheritance.
In the following, class Bar will get a director class that handles
the methods one() and two() (but not three()):
</p>
@ -2961,9 +2966,6 @@ class MyFoo(mymodule.Foo):
<H3><a name="Python_nn34">36.5.2 Director classes</a></H3>
<p>
For each class that has directors enabled, SWIG generates a new class
that derives from both the class in question and a special
@ -3224,7 +3226,7 @@ be able to use std::vector, std::string, etc., as you would any other type.
<p>
<b>Note:</b> The director typemaps for return types based in const
references, such as
references, such as
<div class="code">
<pre>
@ -3498,7 +3500,7 @@ def bar(*args):
$action
#do something after
%}
class Foo {
public:
int bar(int x);
@ -3507,7 +3509,7 @@ public:
</div>
<p> where <tt>$action</tt> will be replaced by the call to
the C/C++ proper method.
the C/C++ proper method.
</p>
<p>
@ -3525,7 +3527,7 @@ proxy, just before the return statement.
<pre>
%module example
// Add python code to bar()
// Add python code to bar()
%feature("pythonprepend") Foo::bar(int) %{
#do something before C++ call
@ -3535,7 +3537,7 @@ proxy, just before the return statement.
#do something after C++ call
%}
class Foo {
public:
int bar(int x);
@ -3554,7 +3556,7 @@ SWIG version 1.3.28 you can use the directive forms
<pre>
%module example
// Add python code to bar()
// Add python code to bar()
%pythonprepend Foo::bar(int) %{
#do something before C++ call
@ -3564,7 +3566,7 @@ SWIG version 1.3.28 you can use the directive forms
#do something after C++ call
%}
class Foo {
public:
int bar(int x);
@ -3658,7 +3660,7 @@ Vector(2, 3, 4)
</div>
<p>
<tt>%extend</tt> can be used for many more tasks than this.
<tt>%extend</tt> can be used for many more tasks than this.
For example, if you wanted to overload a Python operator, you might do this:
</p>
@ -3687,7 +3689,7 @@ Use it like this:
&gt;&gt;&gt; w = example.Vector(10, 11, 12)
&gt;&gt;&gt; print v+w
Vector(12, 14, 16)
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre>
</div>
@ -3991,7 +3993,7 @@ int send_message(char *text, int *success);
</div>
<p>
When used in Python, the function will return multiple values.
When used in Python, the function will return multiple values.
</p>
<div class="targetlang">
@ -4142,7 +4144,7 @@ int sumitems(int *first, int nitems) {
</div>
<p>
To wrap this into Python, you need to pass an array pointer as the first argument.
To wrap this into Python, you need to pass an array pointer as the first argument.
A simple way to do this is to use the <tt>carrays.i</tt> library file. For example:
</p>
@ -4219,13 +4221,13 @@ using the <tt>cstring.i</tt> library file described in the <a href="Library.html
</p>
<p>
When functions return a <tt>char *</tt>, it is assumed to be a NULL-terminated string.
When functions return a <tt>char *</tt>, it is assumed to be a NULL-terminated string.
Data is copied into a new Python string and returned.
</p>
<p>
If your program needs to work with binary data, you can use a typemap
to expand a Python string into a pointer/length argument pair. As luck would have it,
to expand a Python string into a pointer/length argument pair. As luck would have it,
just such a typemap is already defined. Just do this:
</p>
@ -4260,7 +4262,7 @@ also be used to extra binary data from arbitrary pointers.
<p>
C++ default argument code generation is documented in the main
<a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a> section.
There is also an optional Python specific feature that can be used called the <tt>python:cdefaultargs</tt>
There is also an optional Python specific feature that can be used called the <tt>python:cdefaultargs</tt>
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
By default, SWIG attempts to convert C++ default argument values
into Python values and generates code into the Python layer containing these values.
@ -4303,7 +4305,7 @@ class CDA(object):
<p>
Adding the feature:
</p>
<div class="code">
<pre>
%feature("python:cdefaultargs") CDA::fff;
@ -4364,7 +4366,7 @@ as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
</p>
<p>
Before proceeding, it should be stressed that typemaps are not a required
Before proceeding, it should be stressed that typemaps are not a required
part of using SWIG---the default wrapping behavior is enough in most cases.
Typemaps are only used if you want to change some aspect of the primitive
C-Python interface or if you want to elevate your guru status.
@ -4374,7 +4376,7 @@ C-Python interface or if you want to elevate your guru status.
<p>
A typemap is nothing more than a code generation rule that is attached to
A typemap is nothing more than a code generation rule that is attached to
a specific C datatype. For example, to convert integers from Python to C,
you might define a typemap like this:
</p>
@ -4506,7 +4508,7 @@ like this:
<p>
A detailed list of available methods can be found in the "<a
href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
</p>
<p>
@ -4568,7 +4570,7 @@ A <tt>PyObject *</tt> that holds the result to be returned to Python.
</p>
<div class="indent">
The parameter name that was matched.
The parameter name that was matched.
</div>
<p>
@ -4812,7 +4814,7 @@ In the example, two different typemaps are used. The "in" typemap is
used to receive an input argument and convert it to a C array. Since dynamic
memory allocation is used to allocate memory for the array, the
"freearg" typemap is used to later release this memory after the execution of
the C function.
the C function.
</p>
<H3><a name="Python_nn60">36.9.2 Expanding a Python object into multiple arguments</a></H3>
@ -4878,7 +4880,7 @@ previous example:
</div>
<p>
When writing a multiple-argument typemap, each of the types is referenced by a variable such
When writing a multiple-argument typemap, each of the types is referenced by a variable such
as <tt>$1</tt> or <tt>$2</tt>. The typemap code simply fills in the appropriate values from
the supplied Python object.
</p>
@ -4960,7 +4962,7 @@ A typemap can be used to handle this case as follows :
%module outarg
// This tells SWIG to treat an double * argument with name 'OutValue' as
// an output value. We'll append the value to the current result which
// an output value. We'll append the value to the current result which
// is guaranteed to be a List object by SWIG.
%typemap(argout) double *OutValue {
@ -5312,7 +5314,7 @@ example:
<div class="code">
<pre>
%define DOCSTRING
"The `XmlResource` class allows program resources defining menus,
"The `XmlResource` class allows program resources defining menus,
layout of controls on a panel, etc. to be loaded from an XML file."
%enddef
@ -5607,7 +5609,7 @@ Packages</a> for more information.
<p>
If you place a SWIG generated module into a Python package then there
are details concerning the way SWIG
are details concerning the way SWIG
<a href="#Python_package_search">searches for the wrapper module</a>
that you may want to familiarize yourself with.
</p>
@ -6378,7 +6380,7 @@ In Python:
&gt;&gt;&gt; snprintf(buf, "Hello world!")
&gt;&gt;&gt; print(buf)
bytearray(b'Hello\x00')
&gt;&gt;&gt;
&gt;&gt;&gt;
</pre></div>
</div>
@ -6414,7 +6416,7 @@ bytearray(b'FOO\x00')
<p>
Both <tt>%pybuffer_mutable_binary</tt> and <tt>%pybuffer_mutable_string</tt>
require the provided buffer to be mutable, eg. they can accept a
require the provided buffer to be mutable, eg. they can accept a
<tt>bytearray</tt> type but can't accept an immutable <tt>byte</tt>
type.
</p>
@ -6730,6 +6732,110 @@ the first is allowing unicode conversion and the second is explicitly
prohibiting it.
</p>
<H2><a name="Python_multithreaded">36.13 Support for Multithreaded Applications</a></H2>
<p>By default, SWIG does not enable support for multithreaded Python applications. More
specifically, the Python wrappers generated by SWIG will not release the
Python's interpreter's Global Interpreter Lock (GIL) when wrapped C/C++ code is
entered. Hence, while any of the wrapped C/C++ code is executing, the Python interpreter
will not be able to run any other threads, even if the wrapped C/C++ code is waiting
in a blocking call for something like network or disk IO.
Fortunately, SWIG does have the ability to enable multithreaded support and automatic
release of the GIL either for all wrapped code in a module or on a more selective basis. The user
interface for this is described in the next section.
</p>
<H3><a name="Python_thread_UI">36.13.1 UI for Enabling Multithreading Support</a></H3>
<p>The user interface is as follows:</p>
<ol>
<li><p>Module thread support can be enabled in two ways:</p>
<ul>
<li>
<p>
The <tt>-threads</tt> swig python option at the command line (or in <tt>setup.py</tt>):
</p>
<div class="shell"><pre>$ swig -python -threads example.i</pre></div>
</li>
<li>
<p>
The <tt>threads</tt> module option in the *.i template file:
</p>
<div class="code"><pre>%feature("nothread") method;</pre></div>
</li>
</ul>
</li>
<li><p>You can disable thread support for a given method:</p>
<div class="code"><pre>%module("threads"=1)</pre></div>
or
<div class="code"><pre>%nothread method;</pre></div>
</li>
<li><p>You can partially disable thread support for a given method:</p>
<ul>
<li><p>To disable the C++/python thread protection:</p>
<div class="code"><pre>%feature("nothreadblock") method;</pre></div>
or
<div class="code"><pre>%nothreadblock method;</pre></div>
</li>
<li>
<p>To disable the python/C++ thread protection</p>
<div class="code"><pre>%feature("nothreadallow") method;</pre></div>
or
<div class="code"><pre>%nothreadallow method;</pre></div>
</li>
</ul>
</li>
</ol>
<H3><a name="Python_thread_performance">36.13.2 Multithread Performance</a></H3>
<p>
For the curious about performance, here are some numbers for the profiletest.i test,
which is used to check the speed of the wrapped code:
</p>
<table summary="Python multithread performance">
<tr>
<th>Thread Mode</th>
<th>Execution Time (sec)</th>
<th>Comment</th>
</tr>
<tr>
<td>Single Threaded</td>
<td>9.6</td>
<td>no "-threads" option given</td>
</tr>
<tr>
<td>Fully Multithreaded</td>
<td>15.5</td>
<td>"-threads" option = 'allow' + 'block'</td>
</tr>
<tr>
<td>No Thread block</td>
<td>12.2</td>
<td>only 'allow'</td>
</tr>
<tr>
<td>No Thread Allow</td>
<td>13.6</td>
<td>only block'</td>
</tr>
</table>
<p>
Fullly threaded code decreases the wrapping performance by
around 60%. If that is important to your application, you
can tune each method using the different 'nothread',
'nothreadblock' or 'nothreadallow' features as
needed. Note that for some methods deactivating the
'thread block' or 'thread allow' code is not an option,
so, be careful.
</p>
</body>
</html>