From 52d12bc415f24c13bebb0bcfaaaa868df3bc83d8 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Tue, 28 Feb 2017 20:53:30 -0500 Subject: [PATCH 1/3] Started making changes to Python.html to document support for multithreaded Python SWIG applications. --- Doc/Manual/Python.html | 206 ++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 85 deletions(-) diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index a5b2100ce..dfb38e942 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -133,6 +133,10 @@
  • Byte string output conversion
  • Python 2 Unicode +
  • Support for Multithreaded Applications + @@ -162,7 +166,7 @@ Basics" chapter.

    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.

    @@ -395,9 +399,9 @@ $ gcc -shared example.o example_wrap.o -o _example.so

    -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 SWIG/Examples/python +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 SWIG/Examples/python 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 SWIG Wiki for @@ -409,7 +413,7 @@ When linking the module, the name of the output file has to match the name of the module prefixed by an underscore. If the name of your module is "example", then the name of the corresponding object file should be "_example.so" or "_examplemodule.so". -The name of the module is specified using the %module directive or the +The name of the module is specified using the %module directive or the -module command line option.

    @@ -433,7 +437,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.

    @@ -493,7 +497,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).

    @@ -552,13 +556,13 @@ Another possible error is the following: Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: dynamic module does not define init function (init_example) ->>> +>>>

    -This error is almost always caused when a bad name is given to the shared object file. -For example, if you created a file example.so instead of _example.so 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 example.so instead of _example.so 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 %module directive. Double-check the interface to make sure the module name and the shared object @@ -584,7 +588,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.

    @@ -619,7 +623,7 @@ problem when you try to use your module: Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: libfoo.so: cannot open shared object file: No such file or directory ->>> +>>> @@ -642,7 +646,7 @@ $ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \

    Alternatively, you can set the LD_LIBRARY_PATH environment variable to -include the directory with your shared libraries. +include the directory with your shared libraries. If setting LD_LIBRARY_PATH, 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 +711,7 @@ $ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun

    -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.

    @@ -715,8 +719,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.

    @@ -760,7 +764,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.

    @@ -814,10 +818,10 @@ If you need to build it on your own, the following notes are provided:

    -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 +856,7 @@ settings, select the "Custom Build" option. "C++:Preprocessor". Add the include directories for your Python installation under "Additional include directories". -

  • Define the symbol __WIN32__ under preprocessor options. +
  • Define the symbol __WIN32__ under preprocessor options.
  • Finally, select the settings for the entire project and go to "Link Options". Add the Python library file to your link libraries. @@ -866,7 +870,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.

    @@ -885,9 +889,9 @@ $ python

    If you get an ImportError 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.

    @@ -938,7 +942,7 @@ wrapped into a Python 'example' module. Underneath the covers, this module consists of a Python source file example.py and a low-level extension module _example.so. 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.

    36.3.2 Functions

    @@ -991,8 +995,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.

    @@ -1038,7 +1042,7 @@ error message. For example: Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: C variable 'density (double )' ->>> +>>>

    @@ -1188,7 +1192,7 @@ simply represented as opaque values using an especial python container object:

    This pointer value can be freely passed around to different C functions that -expect to receive an object of type FILE *. The only thing you can't do is +expect to receive an object of type FILE *. 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.

    @@ -1309,7 +1313,7 @@ is used as follows: >>> v.y = 7.2 >>> print v.x, v.y, v.z 7.8 -4.5 0.0 ->>> +>>>

    @@ -1368,7 +1372,7 @@ struct Foo {

    When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (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).

    @@ -1395,7 +1399,7 @@ If accessed in Python, you will see behavior like this: >>> b = example.Bar() >>> print b.x _801861a4_p_int ->>> +>>> @@ -1460,7 +1464,7 @@ Foo *x = &b->f; /* Points inside b */

    -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:

    @@ -1468,7 +1472,7 @@ everything works just like you would expect. For example:
     >>> b = Bar()
     >>> b.f.a = 3               # Modify attribute of structure member
    ->>> x = b.f                   
    +>>> x = b.f
     >>> x.a = 3                 # Modifies the same structure
     
    @@ -1510,13 +1514,13 @@ you can use it in Python like this:

    -Class data members are accessed in the same manner as C structures. +Class data members are accessed in the same manner as C structures.

    -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:

    @@ -1669,10 +1673,10 @@ const Foo &spam9();

    then all three functions will return a pointer to some Foo 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.

    @@ -1771,7 +1775,7 @@ To fix this, you either need to ignore or rename one of the methods. For exampl
     %rename(spam_short) spam(short);
     ...
    -void spam(int);    
    +void spam(int);
     void spam(short);   // Accessed as spam_short
     
    @@ -1784,7 +1788,7 @@ or
     %ignore spam(short);
     ...
    -void spam(int);    
    +void spam(int);
     void spam(short);   // Ignored
     
    @@ -1797,7 +1801,7 @@ first declaration takes precedence.

    -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.

    36.3.11 C++ operators

    @@ -1823,7 +1827,7 @@ public: Complex operator-(const Complex &c) const; Complex operator*(const Complex &c) const; Complex operator-() const; - + double re() const { return rpart; } double im() const { return ipart; } }; @@ -2005,7 +2009,7 @@ In Python:

    Obviously, there is more to template wrapping than shown in this example. -More details can be found in the SWIG and C++ chapter. +More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later.

    @@ -2188,7 +2192,7 @@ These wrappers can be found in the low-level extension module (e.g., _exampl

    -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):

    @@ -2210,7 +2214,7 @@ class Foo(object):

    -This class merely holds a pointer to the underlying C++ object (.this) and dispatches methods and +This class merely holds a pointer to the underlying C++ object (.this) 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:

    @@ -2254,7 +2258,7 @@ class Foo(object):

    When a Foo instance is created, the call to _example.new_Foo() -creates a new C++ Foo instance; wraps that C++ instance inside an instance of +creates a new C++ Foo instance; wraps that C++ instance inside an instance of a python built-in type called SwigPyObject; and stores the SwigPyObject instance in the 'this' field of the python Foo object. Did you get all that? So, the python Foo object is composed of three parts:

    @@ -2545,7 +2549,7 @@ public:

    -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 MyClass:

    @@ -2609,7 +2613,7 @@ when the -builtin option is used.

    Associated with proxy object, is an ownership flag .thisown 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.

    @@ -2712,7 +2716,7 @@ is assigned to a global variable. For example: >>> f = example.Foo() >>> f.thisown 1 ->>> example.cvar.head = f +>>> example.cvar.head = f >>> f.thisown 0 >>> @@ -2813,7 +2817,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.

    @@ -2883,18 +2887,18 @@ option to the %module directive, like this:

    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:

     // 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;
     
    @@ -2912,11 +2916,11 @@ directors for specific classes or methods. So for example,

    will generate directors for all virtual methods of class Foo except -bar(). +bar().

    -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()):

    @@ -2961,7 +2965,7 @@ class MyFoo(mymodule.Foo):

    36.5.2 Director classes

    - +

    @@ -3224,7 +3228,7 @@ be able to use std::vector, std::string, etc., as you would any other type.

    Note: The director typemaps for return types based in const -references, such as +references, such as

    @@ -3498,7 +3502,7 @@ def bar(*args):
         $action
         #do something after
     %}
    -    
    +
     class Foo {
     public:
         int bar(int x);
    @@ -3507,7 +3511,7 @@ public:
     

    where $action will be replaced by the call to -the C/C++ proper method. +the C/C++ proper method.

    @@ -3525,7 +3529,7 @@ proxy, just before the return statement.

     %module example
     
    -// Add python code to bar() 
    +// Add python code to bar()
     
     %feature("pythonprepend") Foo::bar(int) %{
         #do something before C++ call
    @@ -3535,7 +3539,7 @@ proxy, just before the return statement.
         #do something after C++ call
     %}
     
    -    
    +
     class Foo {
     public:
         int bar(int x);
    @@ -3554,7 +3558,7 @@ SWIG version 1.3.28 you can use the directive forms
     
     %module example
     
    -// Add python code to bar() 
    +// Add python code to bar()
     
     %pythonprepend Foo::bar(int) %{
         #do something before C++ call
    @@ -3564,7 +3568,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 +3662,7 @@ Vector(2, 3, 4)
     
     
     

    -%extend can be used for many more tasks than this. +%extend can be used for many more tasks than this. For example, if you wanted to overload a Python operator, you might do this:

    @@ -3687,7 +3691,7 @@ Use it like this: >>> w = example.Vector(10, 11, 12) >>> print v+w Vector(12, 14, 16) ->>> +>>>
    @@ -3991,7 +3995,7 @@ int send_message(char *text, int *success);

    -When used in Python, the function will return multiple values. +When used in Python, the function will return multiple values.

    @@ -4142,7 +4146,7 @@ int sumitems(int *first, int nitems) {

    -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 carrays.i library file. For example:

    @@ -4219,13 +4223,13 @@ using the cstring.i library file described in the Default arguments section. -There is also an optional Python specific feature that can be used called the python:cdefaultargs +There is also an optional Python specific feature that can be used called the python:cdefaultargs feature flag. 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 +4307,7 @@ class CDA(object):

    Adding the feature:

    - +
     %feature("python:cdefaultargs") CDA::fff;
    @@ -4364,7 +4368,7 @@ as the material in the "Typemaps" chapter.
     

    -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 +4378,7 @@ C-Python interface or if you want to elevate your guru status.

    -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:

    @@ -4506,7 +4510,7 @@ like this:

    A detailed list of available methods can be found in the "Typemaps" chapter. +href="Typemaps.html#Typemaps">Typemaps" chapter.

    @@ -4568,7 +4572,7 @@ A PyObject * that holds the result to be returned to Python.

    -The parameter name that was matched. +The parameter name that was matched.

    @@ -4812,7 +4816,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.

    36.9.2 Expanding a Python object into multiple arguments

    @@ -4878,7 +4882,7 @@ previous example:

    -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 $1 or $2. The typemap code simply fills in the appropriate values from the supplied Python object.

    @@ -4960,7 +4964,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 +5316,7 @@ example:
     %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 +5611,7 @@ Packages for more information.
     
     

    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 searches for the wrapper module that you may want to familiarize yourself with.

    @@ -6378,7 +6382,7 @@ In Python: >>> snprintf(buf, "Hello world!") >>> print(buf) bytearray(b'Hello\x00') ->>> +>>>
    @@ -6414,7 +6418,7 @@ bytearray(b'FOO\x00')

    Both %pybuffer_mutable_binary and %pybuffer_mutable_string -require the provided buffer to be mutable, eg. they can accept a +require the provided buffer to be mutable, eg. they can accept a bytearray type but can't accept an immutable byte type.

    @@ -6730,6 +6734,38 @@ the first is allowing unicode conversion and the second is explicitly prohibiting it.

    +

    36.13 Support for Multithreaded Applications

    + +

    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. +

    + +

    36.13.1 UI for Enabling Multithreading Support

    + +

    The user interface is as follows:

    +
      +
    1. Module thread support can be enabled in two ways: +
        +
      • + The -threads swig python option at the command line (or in setup.py): +
        $ swig -python -threads example.i
        +
      • +
      • + The threads module option in the *.i template file: +
        %module("threads"=1)
        +
      • +
      +
    2. +
    + From bcf8d927f09fbce361dcdeef3285ef4303c61801 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Wed, 1 Mar 2017 17:51:47 -0500 Subject: [PATCH 2/3] Finished updating Python docs for -threads option --- Doc/Manual/Python.html | 61 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index dfb38e942..c0a7911d1 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -136,6 +136,7 @@
  • Support for Multithreaded Applications @@ -6760,12 +6761,70 @@ will not be able to run any other threads, even if the wrapped C/C++ code is wai
  • The threads module option in the *.i template file: -
    %module("threads"=1)
    +
    %feature("nothread") method;
    +
  • + +
  • +
  • You can disable thread support for a given method: +
    %module("threads"=1)
    or
    %nothread method;
    +
  • +
  • You can partially disable thread support for a given method: +
      +
    • To disable the C++/python thread protection: +
      %feature("nothreadblock") method;
      or
      %nothreadblock method;
      +
    • +
    • + To disable the python/C++ thread protection +
      %feature("nothreadallow") method;
      or
      %nothreadallow method;
  • +

    36.13.2 Multithread Performance

    +

    + 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: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Thread ModeExecution Time (sec)Comment
    Single Threaded9.6no "-threads" option given
    Fully Multithreaded15.5"-threads" option = 'allow' + 'block'
    No Thread block12.2only 'allow'
    No Thread Allow13.6only block'
    + +

    + 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. +

    + From d888fabc0ce223873e574414595776c65ca42a73 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 24 Mar 2017 08:22:16 +0000 Subject: [PATCH 3/3] Style fixes for Python threads documentation changes --- Doc/Manual/Contents.html | 5 +++ Doc/Manual/Python.html | 71 +++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index f196da53c..56afca857 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -1614,6 +1614,11 @@
  • Byte string output conversion
  • Python 2 Unicode +
  • Support for Multithreaded Applications + diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index c0a7911d1..92488413e 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -2966,9 +2966,6 @@ class MyFoo(mymodule.Foo):

    36.5.2 Director classes

    - - -

    For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special @@ -6737,6 +6734,7 @@ prohibiting it.

    36.13 Support for Multithreaded Applications

    +

    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 @@ -6751,43 +6749,56 @@ will not be able to run any other threads, even if the wrapped C/C++ code is wai

    36.13.1 UI for Enabling Multithreading Support

    +

    The user interface is as follows:

      -
    1. Module thread support can be enabled in two ways: -
        -
      • - The -threads swig python option at the command line (or in setup.py): -
        $ swig -python -threads example.i
        -
      • -
      • - The threads module option in the *.i template file: -
        %feature("nothread") method;
        -
      • -
      -
    2. -
    3. You can disable thread support for a given method: -
      %module("threads"=1)
      or
      %nothread method;
      -
    4. -
    5. You can partially disable thread support for a given method: -
        -
      • To disable the C++/python thread protection: -
        %feature("nothreadblock") method;
        or
        %nothreadblock method;
        -
      • -
      • - To disable the python/C++ thread protection -
        %feature("nothreadallow") method;
        or
        %nothreadallow method;
        -
      • -
      -
    6. +
    7. Module thread support can be enabled in two ways:

      +
        +
      • +

        + The -threads swig python option at the command line (or in setup.py): +

        +
        $ swig -python -threads example.i
        +
      • +
      • +

        + The threads module option in the *.i template file: +

        +
        %feature("nothread") method;
        +
      • +
      +
    8. +
    9. You can disable thread support for a given method:

      +
      %module("threads"=1)
      + or +
      %nothread method;
      +
    10. +
    11. You can partially disable thread support for a given method:

      +
        +
      • To disable the C++/python thread protection:

        +
        %feature("nothreadblock") method;
        + or +
        %nothreadblock method;
        +
      • +
      • +

        To disable the python/C++ thread protection

        +
        %feature("nothreadallow") method;
        + or +
        %nothreadallow method;
        +
      • +
      +

    36.13.2 Multithread Performance

    + +

    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:

    - +
    Thread Mode Execution Time (sec)