Skip to content

6. Basic Examples

Farzd Safa edited this page Dec 10, 2025 · 9 revisions

6. Basic Examples

Content:


6.1 Overview

The examples presented in this wiki page represent a development transition from fundamental to everyday programs which are designed with an added emphasis on:

  • developing GUI applications with XCOFDK for Python,
  • considerations related to application's task model,
  • program performance, especially its responsiveness,
  • the impact of GIL and achievable performance improvement if disabled,
  • developing of program's UI content rapidly constructed using framework's subsystem for messaging.

The choice of providing the basic examples as GUI programs is chiefly motivated by the fact that the graphical presentation is best suited to illustrate the intended purpose. On the other hand, it also demonstrates the unique pattern of use of framewokr's public API by a program regardless of whether it is a console or GUI application.

There are two implementation versions available for the multithreading examples presented here:


NOTE:

  • Even though the public API of the framewrok is a rich set of both interfaces classes and functions, each
    of the examples only use a small subset of them according to their specific functionality.
  • And as all examples use framework's support for multithreading and/or multiprocessing out-of-the-box,
    the programming effort needed to develop each of them is essentially given by the application-specific
    complexity, especially by their specific UI layout of GUI applications.
  • The example program runs shown in this wiki page all use the stable Python version 3.14.0 which the
    framework of XCOFDK considers the first Python release officially supporting free-threading (FT):
    • either with python3.14 for GIL enabled:
      $> python3.14 -VV
      Python 3.14.0 (main, Oct 22 2025, ...
    • or with python3.14t for GIL disabled:
      $> python3.14t -VV
      Python 3.14.0 free-threading build (main, Oct 22 2025, ...
  • For convenient, especially for experimenting purposes, all examples are also available as archive files:


[Top]

6.1.1 MVC Pattern of GUI Programs

Almost all programs presented here are multithreaded GUI applications designed according to the well-known pattern Model-View-Controller¹ (MVC). The class diagram below illustrates the common design of the GUI's base view:

MVC Design - Base View
  • UserAppControllerIF:
    common base interface with application's controller component (with access to both model and view) is derived from,
  • UserAppModelIF:
    common base interface with application-specific data model (or container) is derived from,
  • UserAppViewIF:
    common base interface with application-specific view(s) are derived from,
  • STGuiAppWelcome:
    base, concrete view class derived from the above-mentioned interface class UserAppViewIF.

[Top]

6.1.2 Base View of GUI Programs

As indicated in the previous section, the class STGuiAppWelcome is designed to serve as a reusable basis for the graphical interface of all GUI applications.
A given basic example creates an instance of STGuiAppWelcome (or just the GUI for short) while adding application-specific child views to it to achieve its specific graphical interface. The general grid layout is depicted below:

# Simplified grid layout of class 'STGuiAppWelcome':
#     +=============================================+
#     | Info frame                                  |
#     +---------------------------------------------+
#     | GUI action frame                            |
#     +---------------------------------------------+
#     | Child frames (if any)...                    |
#     +=============================================+

The implementation of the graphical interface provided by class STGuiAppWelcome usesn the GUI toolkit tkinter².
The main responsibility of the GUI is to create the root window (including child views) and to manage its event loop when started. Two optional command line arguments can be supplied:

  • --help
    print usage and exit,
  • --disable-auto-start
    do not run the GUI Action by default upon program start. It defaults to False,
  • --enable-auto-close
    close the GUI immediately if the GUI Action is not running currently, or after its completion otherwise. It defaults to False.

The code snippet below shows how to start the GUI via command line as a standalone, singlethreaded program:

$> cd /path/to/parent/folder/of/stguiappwelcome.py/
$>
$> # run the script for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m stguiappwelcome

The screenshot below shows the output of the program:

Base GUI View Welcome

The GUI Action frame shown above is designed as a replacement of whatever an arbitrary application would have to perform in terms of GUI operations. It especially also represents program's most important performance metric, namely the responsiveness, by providing a graphical indicatior consisting of a progress bar and the amount of time it takes for the GUI to refill the progress bar when restarted.

Unless stopped or paused by the user, the GUI Action is restarted by the GUI in a cyclic manner, except for the singlethreaded execution of STGuiAppWelcome shown above. While the perceived speed of the progress bar (when running) is a graphical visualization of the quality of current responsiveness already, a rough by-value-comparison of the elapsed time compared to the singlethreaded version may provide more expressive assessments (of the task model) of the example at hand.


[Top]

6.1.3 Common Design of GUI Programs

Common for all example programs is a main module which provides a Main() function acting as the entry point of the application. Its general layout is inspired by the common pattern of use of the control functions of the subsystem fwctrl. When called, the main responsibility of Main() is as follows:

  • modify the RTE configuration (if needed),
  • start of the framework,
  • create and start applications main task (acting as the starter task),
  • wait for the framework to terminate.

[Top]

6.1.3.1 Class Diagram of RC Examples

As discussed in section 4.2.2 3-PhXF of Task Instances, the execution frmae of an RC task can be specified either by ordinary callback functions or by (an instance) of a XF-like class. The RC examples, however, are rather developed using the XF-like approach as most of the applications tasks do also have to maintain their specific per-instance data which directly or indirectly contribute to the UI content to be presented.

The class diagram below illustrates the application design common for all RC example:

MVC Design - RC Examples
  • XFMainTask:
    represents the execution frame of application's main task which is a user-defined XF-like class:
    • derived from UserAppControllerIF, it is the controller of application's MVC design, too,

    • instance member gui refers to the GUI instance of the application,

    • the main task may or may not maintain service tasks (see below), child processes and the model instance of application's MVC design,

    • instance member myTask refers to the current running task which executes the main task.
      With the code snippet below given (see RC exampleB11), more precisely it refers to the RC task instance, e.g. _myMT below, created by supplying an instance of this class, e.g. _phasedXFCallback below, as its execution frame:

      # file : rc/exampleB11/mtguiapp.py
      #...
      
      from xuserapp.basic.xmt.rc.exampleB11.maintask import _CreateMainTask
      
      def Main(cmdLineOpts_ : CLOptions):
          #...
      
          # step 2: create main task
          _myMT = _CreateMainTask(cmdLineOpts_)
      
          # step 3: start framework
          fwapi.StartXcoFW(fwStartOptions_=cmdLineOpts_.GetSuppliedFwOptions()
      
          # step 4: start main task
          _myMT.Start('sample positional argument', kwArg_='sample keyword argument')
      
          #...
      # file : rc/exampleB11/maintask.py
      #...
      
      from xcofdk.fwapi import XFSyncTask
      from xcofdk.fwapi import XFAsyncTask
      
      from xuserapp.st.welcome.interfaces.controllerif import UserAppControllerIF
      
      def _CreateMainTask(cmdLineOpts_ : CLOptions) -> IRCTask:
          _aliasName        = 'MainTask'
          _phasedXFCallback = XFMainTask(cmdLineOpts_)
          if cmdLineOpts_.isAsynMainTaskEnabled:
              res = XFAsyncTask(_phasedXFCallback, aliasName_=_aliasName, bMainTask_=True)
          else:
              res = XFSyncTask(_phasedXFCallback, aliasName_=_aliasName, bMainTask_=True)
          return res
      
      class XFMainTask(UserAppControllerIF):
          #...

      The main task especially serves as application's starter task, that is that task instance (of application's task model) which is started as the first one once the framework is started, as shown by step 4 above,

  • XFServiceTask:
    represents the execution frame of a service task which is a user-defined XF-like class, too:
    • in general, service tasks (if any) are designed to perform some application-specific communication with the main task via subsystem messaging,
    • instance member myTask refers to the current running task which executes the respective instance of this class.
      With the code snippet below given (see servicetask.py), more precisely it refers to the RC task instance, e.g. the returned value res below, created by supplying an instance of this class, e.g. _phasedXFCallback below, as its execution frame:
      # file : rc/rcmisc/servicetask.py
      #...
      
      from xcofdk.fwapi import XFAsyncCommTask
      
      def CreateServiceTask( srvTaskNo_          : int
                           , bBroadcast_         =False
                           , bSkipPayloadSerDes_ =False
                           , bCustomPayLoad_     =False) -> IRCCommTask:
          #...
          _phasedXFCallback = XFServiceTask( bBroadcast_=bBroadcast_
                                           , bSkipPayloadSerDes_=bSkipPayloadSerDes_
                                           , bCustomPayLoad_=bCustomPayLoad_)
      
          res = XFAsyncCommTask(_phasedXFCallback, aliasName_=_aliasName, runCallbackFrequency_=20)
          return res
      
      class XFServiceTask:
          #...

[Top]

6.1.3.2 Class Diagram of SC Examples

The SC examples are the subclassing counterpart of the RC examples, so they provide exactly the same program behavior. They differ from the RC examples in that both the main task and service tasks are created following the subclassing approach. The class diagram below illustrates the application design common for all SC example:

MVC Design - SC Examples

[Top]

6.1.4 Common Program Options

An overview of optional command line arguments available for all basic GUI examples is shown in the table below:

Argument : Description
-h : print usage and exit
--help : ditto
--log-level LOG_LEVEL : see API function StartXcoFW()
--fw-log-level FW_LOG_LEVEL : ditto
--disable-log-timestamp : ditto
--disable-log-highlighting : ditto
--disable-log-callstack : ditto
--bypass-free-threading-guard : see API function RtePolicyBypassExperimentalFreeThreadingGuard()
--disable-auto-start : explained here
--disable-auto-close : ditto

NOTE:

  • Color highlighting of the log output is supported for Python versions 3.9 and higher. In general, the start
    option --disable-log-highlighting should always be supplied whenever used console program of
    the platform, e.g. Windows Commond Prompt cmd.exe, does not support colored output to stdout.
  • The framework supports the stable version 3.14.0 being the first Python version officially supporting
    free-threaded (FT) Python.
  • Python versions 3.13 and pre-releases of 3.14.0 are rather considered by the framework supporting
    experimental free-threaded Python only.
    Accordingly, whenever using these interpreter versions, a pre-configuration of the RTE via the policy
    function RtePolicyBypassExperimentalFreeThreadingGuard() remains mandatory.

[Top]


6.2 Multithreading with GIL enabled

6.2.1 exampleB11 with GIL

The GUI application exampleB11 is the multithreaded counterpart of the singlethreaded base view STGuiAppWelcome. It uses its main task to (a)synchronously start the GUI.

Application modules:


Optional command line argument(s):

In addition to the common program options, available optional command line argument(s) are as follows:

Argument : Description
--async-main-task : make the execution type of the main task is asynchronous instead of
synchronous

The code snippet below shows how to start exampleB11 via command line:

$> cd /path/to/subfolder/exampleB11/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mtguiapp

The screenshot below shows the UI of the program (see also section 6.3.1 exampleB11 without GIL for a performance comparison):

exampleB11 with GIL

[Top]


6.2.2 exampleB21 with GIL

The GUI application exampleB21 represents the generic master of a family of GUI applications designed to demonstrate basic features of the subsystem messaging. Except for the UI content constructed according to their specific use case of messaging, they all have a similar GUI appearance:

The following subsections discuss the example21 as the master representative of this group of example programs in more detail.

Application modules:


Optional command line argument(s):

In addition to the common program options, available optional command line argument(s) are as follows:

Argument : Description
--async-main-task : make the execution type of the main task is asynchronous instead of
synchronous
--service-tasks-count : number of service tasks (in the range of [1..12]) to be created and
started by the main task, defaulting to 12

The code snippet below shows how to start exampleB21 via command line:

$> cd /path/to/subfolder/exampleB21/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mtguiapp

The screenshot below shows the UI of the program with:

  • a GUI action performance of 2.740 [s], which is:

  • ca. 172 [msg/s] transferred, i.e. (sent or received) messages,

  • exampleB21 with GIL enabled:

    exampleB21 with GIL

[Top]

Application Task Model

As indicated above, the main functional purpose of this family of basic examples is to make a heavy use of the API of the messaging subsystem. For this, the main task periodically sends messages to its service tasks and processes their responses or messages. Therefore, the configuration of an appropriate messaging and/or run-phase frequency of each of the involved application tasks is the utmost parameter of the designed task model to make program's responsiveness can be ensured.

Also as for the simplicity, all service tasks of a given application of this family are always instances of the same class. This way, the design of the task model of these examples is basically given by the specification of two configuration items:

  • the frequency of main task's messaging,
  • the run-phase frequency of the service tasks.

[Top]

Messaging Frequency of Main Task

Regardless of the chosen execution type, the run-phase frequency of the main task doesn't matter at all, as it is configured to be non-cyclic. But:


[Top]

Run-phase Frequency of Service Tasks

As opposed to the main task, serivce tasks do not have much to do, as they each merely process a few received messages (if any) and send out one single message (if any) per run-phase iteration, thereby not taking considerable CPU time.

Therefore, a run-phase frequency of 20 [ms] is a promising value to make service tasks are sending out as often as possible, while the total number of messages sent out remains manageable for the main task. So, for the use case of 12 service tasks (as shown in the screenshot above), the total number of messages sent by the service tasks (and received or processed by the main task) is ca. 150 [msg/s]. In other words, the main task has to process a new received message every 6.7 [ms].


[Top]


6.2.3 exampleB31 with GIL

The GUI application exampleB31 is a specialized version of above-presented exampleB21 with added focus on the run-phase frequency of the service tasks which have to execute an additional computation per run-phase loop iteration:

  • in general, the example represents a sample program which might be used as an analysis and/or configuration tool with respect to the run-phase frequency of tasks of similar (GUI) applications, too,
  • while the chosen approach remains unchanged, the outcome of the analysis directly depends on the number of (application) tasks of the program and available resources of the host machine, e.g. memory or number of CPU cores,
  • the following discussion is particularly based on the fix number of 12 service tasks,
  • the utility function UserAppUtil.Fibonacci() is used for the additional calculation requires a significant amount of time based on the non-negative integer number N passed to as input. It is a trivial implementation of the well-known Fibonacci sequence with no optimization applied to. However, note that the chosen utility function here is simply a placeholder for any possible CPU-bound computation to be performed by individual application tasks.

Application modules:

  • mtguiapp.py:
  • maintask.py:
    • in accordance to the common application design of RC examples, it provides the class XFMainTaskGIL which represents main task's execution frame derived from the MVC interface class UserAppControllerIF and capable of full communication,
    • the non-cyclic main task is basically responsible for:
      • dynamic, rough estimation of required run-phase frequency of the service tasks for the Fibonacci input N supplied (see below). The table below shows a sample estimation result based on the reference test environment used for the program runs on Ubuntu:
        Fibonacci input N : CPU time cons. [ms] Run-phase freq. [ms] Deficient run-phase freq. [ms]
        18 : 0.369 4 3
        19 : 0.582 6 5
        20 : 0.953 10 8
        21 : 1.791 19 16
        22 : 2.500 27 22
        23 : 4.272 46 37
        24 : 6.616 72 58
        25 : 11.204 123 99
        26 : 17.326 190 152
      • starting the GUI instance of the program,
      • create and start of the service tasks (see below),
      • initiating continuous data exchange via messaging with the service tasks,
      • update of GUI's UI content based on application's MVC design,
  • servicetaskGIL.py:
    • it provides the class XFServiceTaskGIL, used as the execution frame of asynchronous, cyclic service task instances capable of full communication,
    • in general service instances are also responsible for continuous messaging with the main task as long as they are running,
    • they execute the calculation of the Fibonacci sequence for the supplied input N in each of their run-phase interation, too.

Optional command line argument(s):

In addition to the common program options, available optional command line argument(s) are as follows:

Argument : Description
--fibonacci-input : integer value as input for calculation of Fibonacci sequence by
a service task, valid range is:
[18..26] (defaulting to 18) for Linux platform
[17..26] (defaulting to 17) otherwise
--force-deficient-frequency : make service tasks are configured with a deficient run-phase frequency

Note however, that the estimated (deficient) run-phase frequencies for a given Fibonacci input N may show an almost equal timing behavior of the program depending on the shortes achievable sleep time on the host machine.

The code snippet below shows how to start exampleB31 via command line with 20 supplied as Fibonacci input:

$> cd /path/to/subfolder/exampleB31/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mtguiapp --fibonacci-input 20

The screenshot below shows the UI of the program:

exampleB31 with GIL

Impact of GIL:

In general, a dedicated consideration of the run-phase frequency is a common issue of task model design of multithreaded applications (with or without CPU-bound activity) regardless of additional performance constraints like GIL for Python programs. Only, for Python interpreter versions built with no support for --disable-gil (or whenever sys._is_gil_enabled() (if available) returns True at runtime) the issue becomes an inevitable part of task model's design effort.

A mal-configured run-phase frequency would otherwise make that program's performance suffers from unblanced concurrency resulting in at least insufficient responsiveness of the application. As shown in the UI screenshot above, the average amount of time needed for the GUI action is around 4.0 [sec] for N=20, which is still a quite acceptable value on the reference test environment use for. A noticeable contrast shows up, as soon as the run-phase frequency is forced to be deficient for the same input N=20. Now, the GUI action takes around 5.1 [sec] (and more) with a perceivable jitter effect of the progress bar:

$> cd /path/to/subfolder/exampleB31/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mtguiapp --fibonacci-input 20 --force-deficient-frequency

with below screenshot of the corresponding UI:

exampleB31 with GIL

A highly simplified explanation of the program's performance with mal-configured run-phase frequency is given when the application tasks only are considered, i.e. the main task and the service tasks alone. As GIL is present for the Python version running:

  • the normal scheduling policy applied to tasks (or host threads) is suspended if currently executing a CPU-bound piece of code. Such a task will keep the CPU until completion of that piece of code,
  • accordingly, the service tasks take a continuous, total time of 11.4 [ms] (ca. =12*0.953) to complete the current iteration of the run-phase before the GUI, i.e. the main task, is re-scheduled with CPU,
  • but then, the GUI (as being basically IO-bound due to its event loop) doesn't get the chance of a fairly shared CPU, as the deficient frequency of 8 [ms] is already expired at least for the first service task waiting for CPU. Therefore, the GUI is more or less promptly scheduled off-CPU due to the re-scheduling done by operating system's scheduler,
  • now, the service tasks regain the CPU for the next continuous 11.4 [ms], until the GUI is re-assigned with CPU for the next time,
  • all in all, this high-frequency of re-scheduling with the GUI being interrupted over and over takes place all the time during program execution.

NOTE:

  1. The approach of determining the proper run-phase frequency (of individual tasks) presented here is
    suitable to only a limited extent whenever GIL is around with CPU-bound tasks inherently requiring
    a singnificant amount of CPU time, and so blocking other tasks,
  2. for N=26, for example, the total amount of time needed by the service tasks to complete a given
    iteration of the run-phase loop is 208.0 [ms] (ca. =12*17.326),
  3. accordingly, the responsiveness of the GUI will be suffering anyway, even for sufficiently configured
    run-phase frequency, as the GUI is left with a frequency of ca. 5 times a second only, which is definitely
    too low.

[Top]


6.2.4 exampleB32 with GIL

The GUI application exampleB32 uses a synchronous main task and multiple asynchronous service tasks. It demostrates achievable improvement via optimization of CPU-bound tasks even despite GIL.

The section 6.2.3 exampleB31 with GIL discussed the impact of GIL, especially in the context of CPU-bound tasks for which there may or may not be some way of optimization available in terms of required CPU consumption. Apart from presenting one more hands-on example (for working with the public API of the framework), exampleB32 also is designed to point out below noticeable facts:

  • the framework itself is designed and implemented with GIL in mind, its runtime behavior is not impacted by,
  • multithreading and so the use of multiple application tasks may also help in delegation of program complexity,
  • compared to their singlethreaded counterparts, multithreaded applications, if designed and configured properly, are capable of achieving almost the same or even much better (speed) performance for time critical and/or CPU-bound computation, especially whenever appropriate optimization can be provided.

Application modules:

  • mtguiapp.py:
  • maintask.py:
    • in accordance to the common application design of RC examples, it provides the class XFMainTaskGIL2 which represents main task's execution frame derived from the MVC interface class UserAppControllerIF and capable of full communication,
    • on a regular basis, the main task requests all service tasks to deliver Fibonacci(N) for a list of some selected N<=100,
    • as soon as the first reply is received, the result is displayed,
    • once all service tasks have replied their respective results which happens almost promptly, the request is considered serviced,
    • after a short time, next request is sent out to the service tasks,
  • servicetaskGIL2.py:
    • it provides the class XFServiceTaskGIL2, used as the execution frame of asynchronous, cyclic service task instances capable of full communication,
    • by default, the service tasks (re-)start the calculation of Fibonacci(N) up to N=100 all the time,
    • upon a request from the main task, they delete their respective cache and restart the calculation for the requested list of input N,
    • as soon as done, they reply to the main task with a list of the calculated results,
    • then, the default calculation of Fibonacci takes place again until next request from the main task is received,
    • the optimization used for the Fibonacci calculation by the service instances is given by use of the caching mechanism on one hand (see ServiceTaskGIL2.__CalcFibo()), and allowing the calculation of Fibonacci in any of the iteration of the run-phase loop of the service instances for the next 20 integer numbers only on the other hand (see ServiceTaskGIL2.RunTask()).

Optional command line argument(s):

The available optional command line argument(s) of example32 are described in section 6.1.3 Common Program Options.

The code snippet below shows how to start example32 via command line:

$> cd /path/to/subfolder/exampleB32/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mtguiapp 

The screenshot below shows the UI of the program:

  • the whole calculation (for quite large numbers as the Fibonacci input N requested by the main task) takes less than 110.0 [ms],

  • accordingly, the performance of the GUI action is comparable to the one of the singlethreaded execution of the GUI,
    even though there are at least 12 additional (application) tasks runnig while GIL is around,

  • exampleB32 with GIL enabled:

    exampleB32 with GIL

Certainly, the trivial implementation of the utility function UserAppUtil.Fibonacci() would benefit from the optimization presented above, too, so the Fibonacci calculation could have been done by the main task instead. This approach, however, would at least significantly increase the programming complexity of the main task whose functional responsibility is actually the GUI, plus other high-level or coordinating stuff. Moreover, in case of the availability of an even better optimization, the main task and so its internal organization would have to be changed as well, whereas only the related service task class needs to be adapted only, if the delegation of functional responsibilty applied instead.


[Top]


6.3 Multithreading with GIL disabled

6.3.1 exampleB11 without GIL

The code snippet and screenshot below show the UI of the same program presented in section 6.2.1 exampleB11 with GIL, but this time using the same interpreter version built with GIL disabled:

$> cd /path/to/subfolder/exampleB11/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL disabled
$> python3.14t -m mtguiapp
exampleB11 without GIL

With the GUI Action taken as the key performance indicator, below observations can be pointed out:

  • regardless of its singlethreaded or multithreaded execution (with or without GIL in exampleB11, the performance of the GUI action is almost the same,
  • the pre-configured RTE of the framework does not add any significant overhead to the overall program performance.

[Top]


6.3.2 exampleB21 without GIL

The code snippet below shows how to start the same program presented in section 6.2.2 exampleB21 with GIL, but this time using the same interpreter version built with GIL disabled:

$> cd /path/to/subfolder/exampleB21/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL disabled
$> python3.14t -m mtguiapp

The screenshot below shows the UI of the program with:

  • a GUI action performance of ca. 2.630 [s], which is:

  • ca. 175 [msg/s] transferred, i.e. (sent or received) messages,

  • exampleB21 with GIL disabled:

    exampleB21 without GIL

[Top]


6.3.3 exampleB31 without GIL

The code snippet below shows how to start the same program presented in section 6.2.3 exampleB31 with GIL, but this time using the same interpreter version built with GIL disabled and a relatively larger value of 24 supplied for Fibonacci input numbers N:

$> cd /path/to/subfolder/exampleB31/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL disabled
$> python3.14t -m mtguiapp --fibonacci-input 24 [--force-deficient-frequency]

The screenshot below shows the UI of the program with:


[Top]


6.4 Multiprocessing

6.4.1 exampleMPB11

The GUI application exampleMPB11 is much like exampleB11, except it additionally creates a few child processes, i.e. instances of class XProcess, each of them requested to calculate Fibonacci(N) for a given number. For this, the target of the created child processes is set to the callback function UserAppUtil.Fibonacci() (explained in section 6.2.3 exampleB31 with GIL):

# file: maintask.py

#...
from xcofdk.fwapi              import XProcess
from xuserapp.util.userAppUtil import UserAppUtil

class XFMainTaskMP:
    #...

    def __StartServices(self):
        #...
        for ii in range(self.__srvProcCnt):
            _srvName = 'ServiceProc{:02d}'.format(ii+1)
            _srv     = XProcess(UserAppUtil.Fibonacci, name_=_srvName)
            self.__lstSrv.append(_srv)
            _srv.Start(35+ii)
        #...

Application modules:

  • mpguiapp.py:
  • maintask.py:
    • in accordance to the common application design of RC examples, it provides the class XFMainTaskMP which represents main task's execution frame derived from the MVC interface class UserAppControllerIF. When started, the storyboard of the program is as follows:
      1. create and start three service processes each to calculate Fibonacci(N) with ca. singlethreaded execution time in the reference test environment shown in the table below:
        Fibonacci input N : CPU time cons. [s]
        35 : 1.257
        36 : 2.043
        37 : 3.310
      2. keep going with the GUI with regularly checking for XProcess.isTerminated property of each service instance,
      3. as soon as a service instance is terminated, display its transferred result,
      4. once all running service instances are terminated, continue with 1. after a short while,
    • userAppUtil.py:
      • it provides the utility function UserAppUtil.Fibonacci() used as the callback target of the child processes created by the main task.

Optional command line argument(s):

The available optional command line argument(s) of exampleMPB11 are described in section 6.1.3 Common Program Options.

The code snippet below shows how to start exampleMPB11 via command line:

$> cd /path/to/subfolder/exampleMPB11/
$>
$> # run the application for free-threaded Python 3.14.0 with GIL enabled
$> python3.14 -m mpguiapp 

The screenshot below shows the UI of the program:

exampleMPB11

[Top] [Home] [Previous] [Next][1. Introduction] [2. Quick Start] [3. Architecture] [4. API Overview] [5. Error Handling] [7. Glossary]