diff options
Diffstat (limited to 'doc/singlevsmultiprocess.qdoc')
-rw-r--r-- | doc/singlevsmultiprocess.qdoc | 246 |
1 files changed, 133 insertions, 113 deletions
diff --git a/doc/singlevsmultiprocess.qdoc b/doc/singlevsmultiprocess.qdoc index 871d23c6..43844b81 100644 --- a/doc/singlevsmultiprocess.qdoc +++ b/doc/singlevsmultiprocess.qdoc @@ -29,166 +29,186 @@ /*! \page singlevsmultiprocess.html -\title Single- vs. Multi-Process Mode +\title Single-Process vs. Multi-Process Mode -Single-process mode is only supported by QML applications: applications that use the \c qml or -\c qml-inprocess runtime. Consequently the comparison between single- and multi-process mode only -applies to this kind of applications. In multi-process mode the System-UI (compositor) and the -applications each run in their own dedicated process. In single-process mode, as the name implies, -there is only one process: the System-UI process and all applications run within this process. +The application manager can run the System UI and QML applications in two different modes: -For a better understanding of the two modes, here is how QML works internally: in every process -(aka. address-space), you can only have one Qt platform (QPA) plugin. The QPA plugin decides how -many top-level windows you can open. If you are using a low-level plugin that does not talk to a -windowing system (e.g. EGL full-screen on an embedded device), you can only open one full-screen -window - the System-UI. Now every top-level window can only have one scene-graph and every tree of -QtQuick items needs to be tied to exactly one scene-graph. This means that you will always have -exactly one window, one scene-graph and one QML engine in your System-UI, no matter whether -applications run within the System-UI process or in separate processes. +\list 1 + \li Single-process mode: where the System UI and QML applications are all run in \b one, single + process, that belongs to the System UI. This mode is only supported by QML applications - + applications that use the \qml or \qml-inprocess runtime. + \li Multi-process mode: where the System UI and QML applications all run in their own, dedicated + process. +\endlist + +Internally, for every Qt application, which is ultimately a process, you can have only one Qt +Platform (QPA) Plugin. To interact with the underlying window system, Qt needs to load this plugin +first. The QPA plugin decides how many top-level windows you can open; but Qt can only load one +such plugin at any point and it cannot be switched out at runtime. If you are using a low-level +plugin, one that does not talk to a windowing system, such as EGL full-screen on an embedded +device, you can only open one full screen window: the System UI. + +Now, each top-level window can have only one scene graph, and each tree of QtQuick items needs to +be ties to only one scene graph. Consequently, you will always have only one window, one scene +graph, and one QML engine in your System UI; no matter whether applications run within the +System UI's process, or in separate processes. \section1 Single-process Mode -The single-process mode exists for a reason, and that is to allow: +The single-process mode allows for: + \list -\li Specific system applications to run with maximum performance (no compositing) -\li Scaling down your system to target hardware that has not enough RAM/GPU resources to run - multi-process -\li Do development on platforms that do not (yet) support multi-process mode (read: Windows, macOS, - Android, QNX, any targets with broken Wayland drivers) + \li Specific system applications to run with maximum performance, with no compositing + \li Scaling down your system to target hardware that lacks RAM/GPU resources to run in + multi-process mode + \li Development on platforms that do not yet support multi-process mode, such as Windows, macOS, + Android, QNX, as well as targets with broken Wayland drivers \endlist -All of the above of course comes at the cost of (a) stability and (b) testability (you cannot test -your components isolated, which makes diagnosing errors or crashes very hard). +However, the cost of using single-process mode is reduced stability and testability: you cannot +test your components in isolation, which makes it difficult to diagnose errors or crashes. + +In operating systems, the concept of a process is intertwined with the concept of isolation. +Processes cannot easily affect each other - the operating system ensures this to the best of its +ability. This isolation is crucial, both from a security standpoint and for stability. If a process +crashes, it won't take down another process along the way, for example. -There is one caveat here: you have to be aware that whatever the application-manager may be able to -do, in single-process mode you are still within a single address-space, so you will always be able -to hack your way around any "barrier". The only definite, enforceable barrier is process isolation, -also known as multi-process mode. +Sometimes, this isolation can hinder you, as a developer, if you need to cross this boundary to +communicate with another process. Then, you need to make an effort to do this correctly, by using +dedicated inter-process communication mechanisms, typically available as APIs. +If all your code runs within the same process, then you can avoid the use of tedious and +asynchronous inter-process communication channels. Instead, you can directly access variables and +call functions that you need. -\section1 Build- and Runtime Options +\section1 Configuration -The application-manager is built with multi-process support, if Qt's Wayland compositor module is -available - that is if no special option is provided to qmake: multi-process support can always be -disabled explicitly by adding the option \c {-config force-single-process}. On the other hand if -\c {-config force-multi-process} is provided and the compositor is not available, the configuration -step will fail. +Since single-process mode only has one QML engine, shared amongst the System UI and all +applications, any QML import paths provided, for example via \c am-config.yaml, is taken into +consideration when the engine is resolving import statements. Import statements provided by the +application manifest file, \c info.yaml, are only considered once the application has started, +but is still loaded even after the application has stopped. -In case the application-manager supports only single-process, QML applications that use the \c qml -runtime will always run in-process, i.e. in the same process as the System-UI. Native applications -will be omitted in this case, since they can only run in a dedicated process (of course, native -applications can also use QML code). The difference is basically the entry point: \c native -runtimes have an executable and \c qml runtimes a main QML file. For the latter the -application-manager provides the executable (\c appman-launcher) in multi-process mode. +In multi-process mode, only import paths specific to an application are considered. Additionally, +absolute import paths cannot be used in \c info.yaml files, due to potential restrictions imposed +by containers and for security reasons. -If the application-manager is built with multi-process support, it can still be forced to run in -single-process-mode by passing \c --force-single-process on the command line. This will result in -the same runtime behavior as described above. Even when running the application-manager in -multi-process mode it does not necessarily mean that QML applications get a dedicated process: if -they use the \c qml-inprocess runtime they will execute in-process within the System-UI. +In general, paths defined in the configuration might be provided to QML as absolute paths in +single-process mode; but as relative paths in multi-process mode. +\note In single-process mode, some configuration options have no effect, such as: \c quicklaunch, + \c quicklaunchQml, \c crashAction, and so on. -\section1 Configuration -Since there is only one QML engine in single-process mode shared by the System-UI and all -applications, any QML import paths provided (e.g. through am-config.yaml) will be considered when -resolving import statements. Import statements provided by an application manifest file (info.yaml) -will only be considered once the application has been started, but will outlive its "termination". -In multi-process mode only import paths specific to an application are considered. Besides, -absolute import paths cannot be used in info.yaml files in multi-process mode, because of potential -restrictions imposed by containers and for security reasons. +\section1 Build and Runtime Options -In general paths defined in the configuration might be provided to QML as absolute paths in -single-process mode, but relative in multi-process mode. +The application manager is built with multi-process support, as long as Qt's Wayland compositor +module is available. To disable multi-process support, explicitly specify the +\c {-config force-single-process} option. If you specify the \c {-config force-multi-process} +option, and the compositor is not available, the configuration step fails. -Also note that some configuration options are meaningless in single-process mode, e.g. -\c quicklaunch, \c quicklaunchQml, \c crashAction, etc. +If the application manager supports single-process mode only, QML applications that use the \c qml +runtime will always run in the same process as the System UI. In this case, native applications +are omitted, since they can only run in a dedicated process. This difference is the entry point: +\c native runtimes have an executable and \c qml runtimes have a main QML file. For the latter the +application manager provides the executable (\c appman-launcher) in multi-process mode. + +If the application manager is built with multi-process mode, you can still force it to run in +single-process mode by passing \c --force-single-process on the command line. This results in +the same runtime behavior as described above. Even when running the application manager in +multi-process mode it does not necessarily mean that QML applications get a dedicated process: if +they use the \c qml-inprocess runtime they will execute in-process within the System UI. -\section1 Lifetime +\section1 Application Lifetime -The most obvious difference is that a crashing application in single-process mode will terminate -the entire program, whereas in multi-process mode the System-UI and other applications keep on -running. In multi-process mode the System-UI even gets notified when an application crashed and -can react on it, e.g. by restarting the application. +A key point to note is that, when an application in single-process mode crashes, it terminates the +entire program. In contrast, when an application in multi-process mode crashes, the System UI and +other applications keep on running. In multi-process mode the System UI is even notified when an +application crashes and can react on it, for example by restarting the application. -The usage of QML singletons in an application has some implications. In the QML world, singletons -live in their own private, but also absolutely global context - they are even shared between -multiple QML engine instances. Singletons are instantiated on first usage once and for all, as long -as the process exists. This means that if an application is "terminated" in single-process mode, -any singleton that had already been instantiated will persist and keep its current state. -Consequently, when the application is restarted again, the state might be different from the -multi-process case, where the singleton is instantiated anew. +The usage of QML singletons in an application has some implications. In QML, singletons live in +their own private, but global context - they are even shared between multiple QML engine instances. +Singletons are instantiated on once and for all, on first use, and remain as long as the process +exists. This means that if an application is terminated in single-process mode, any singleton that +was already instantiated will persist and keep its current state. Consequently, when the +application is restarted again, the singleton's state may differ from the multi-process case, where +the singleton is instantiated anew. \section1 Application Windows -A major difference between single- and multi-process mode is how windows are represented. Windows -are exposed from the application to the System-UI through WindowManager::windowReady. For -convenience and to serve as a replacement for Qt's standard \c qmlscene and \c qml tools, it is -possible to use plain QML Windows in applications or even an Item as the root element. However, if -close resemblance between single- and multi-process mode is the goal, there is no way around using -an ApplicationManagerWindow. There are other benefits when using an ApplicationManagerWindow, as -well (e.g. window properties). +Windows are represented differently, whether you run your application in single-process or +multi-process mode. Windows are exposed from the application to the System UI through +\l{WindowManager::windowAdded}. For convenience and to serve as a replacement for Qt's standard +\c qmlscene and \c qml tools, it is possible to use plain QML Windows in applications or even an +Item as the root element. However, if you require close resemblance between single-process and +multi-process mode for your application, you have to use an \l{ApplicationManagerWindow}. There +are also other benefits to using an ApplicationManagerWindow, such as window properties. -In multi-process mode an ApplicationManagerWindow derives from Window and in single-process mode -from QtObject. So several properties coming from Window won't have any effect in single-process -mode, although ApplicationManagerWindow will still define them for compatbility purposes. +In multi-process mode an ApplicationManagerWindow derives from Window; unlike in single-process +mode which derives from QtObject. As a result, several properties coming from Window won't have any +effect in single-process mode, although ApplicationManagerWindow still defines them for +compatibility. The following are some examples: \list -\li An ApplicationManagerWindow is exposed to the System-UI in two different ways: in multi-process - mode a handle to the window's content surface is sent over the process boundary via the Wayland - protocol. The System-UI gets this as a surface Item, which is hierarchically independent from - the application's window. In single-process mode the ApplicationManagerWindow provides its - contentElement Item directly to System-UI. Consequently, it's possible for an application to - gain access to Items from System UI itself or from any other running application as they are - all sharing the same QML scene. -\li Many properties, functions and signals defined in a Window are not reimplemented (yet) in the +\li An ApplicationManagerWindow is exposed to the System UI in two different ways. + \list + \li In multi-process mode, a handle to the window's content surface is sent over the process + boundary via the Wayland protocol. The System UI gets this as a surface Item, which is + hierarchically independent from the application's window. + \li In single-process mode, the ApplicationManagerWindow provides its \c contentElement Item + directly to System UI. Consequently, it's possible for an application to gain access to + Items from System UI itself or from any other running application as they are all + sharing the same QML scene. + \endlist +\li Many properties, functions, and signals defined in a Window are not yet reimplemented in the single-process version of ApplicationManagerWindow. \li An error encountered in a code block due to properties or methods described above will cause - subsequent statements not to be evaluated in multi-process mode, whereas in single-process mode - they are. + subsequent statements not to be evaluated in multi-process mode; but this is not the case in + single-process mode. \endlist \section1 Resource Consumption -CPU usage on a multi-core system might be more efficient in multi-process mode, since the OS can +CPU usage on a multi-core system may be more efficient in multi-process mode, since the OS can schedule more processes and potentially better utilize the cores. -The memory consumption per application in multi-process mode is higher compared to single-process -mode. There is more memory needed by the GPU due to additional window surface buffers that need to -be allocated and also textures that hold application assets are not shared. If two applications -render the same image (file), two textures are created in multi-process mode, in single-process -mode only one. +However, the memory consumption per application in multi-process mode is higher compared to +single-process mode. The GPU needs more memory, to allocate additional window surface buffers. +Also, textures that hold application assets are not shared. If two applications render the same +image file, two textures are created in multi-process mode; instead of one only one in +single-process mode. -The CPU memory consumption per application is higher due to additional data structures, for -instance if one application is running there are two instances of the QML engine in multi-process -mode: one for the System-UI and one for the application. In single-process mode there is only one -instance since everything is running within the System-UI. Also assets might be duplicated in +The CPU memory consumption per application is higher due to additional data structures. For +instance, if one application is running, there are two instances of the QML engine in multi-process +mode: one for the System UI and one for the application. In single-process mode there is only one +instance since everything is running within the System UI. Also assets might be duplicated in multi-process mode. This can be mitigated though, by using shared image providers or by removing -images from CPU memory once they are uploaded to GPU memory (through environment variable -QSG_TRANSIENT_IMAGES). +images from CPU memory once they are uploaded to GPU memory, via the QSG_TRANSIENT_IMAGES +environment variable. On the other hand, multi-process mode comes with the big advantage, that applications which are not -needed any more can be terminated and hence will free their allocated resources again. In -single-process mode applications are never really terminated, so their memory is not freed and the -total consumption grows steadily with each started application, no matter, whether they have been -stopped again. The QML engine simply doesn't allow to unload parts of the object hierarchy. +needed any more can be terminated and hence will free their allocated resources. In single-process +mode applications are never really terminated, so their memory is not freed, causing the total +consumption to grow steadily with each application starting, no matter, whether they have been +stopped. The QML engine doesn't allow you to unload parts of the object hierarchy. -\section1 Recommended Way to Support Mixed Setups +\section1 Support for Single-Process and Multi-Procecss Mode in One Application -Define a set of inter-process communication (IPC) interfaces between the application and System-UI -and stick to them - make this a review policy. You could use any IPC mechanism you see fit, but to -make your lives easier, the application manager comes with an IPC mechanism that already fully -abstracts the single- vs. multi-process difference, plus it makes it easy to create new interfaces -for QML developers. +If your application needs to support both, single-process mode and multi-process mode, you must +define a set of Inter-Process Communication (IPC) interfaces between the application and System UI, +and always stick to them. Consider making these interfaces part of your review policy. While you +can use any IPC mechanism that suits your use case, the application manager includes an IPC +mechanism that fully abstracts the single-process vs. multi-process difference. This mechanism +also makes it easy to create new interfaces for QML developers. -Please be aware that the application-manager IPC is not suitable to interface your complete -middle-ware! Its sole purpose is to avoid a whole zoo of little one-off daemons that would be -needed to keep track of different pieces of state information that need to be shared between the -System-UI and all (or best case, only specific) applications. +Be aware that the application manager's IPC is not suitable to interface your entire middleware. +Its sole purpose is to avoid a situation where there is a large number of one-off daemons that need +to be kept track of, involving various pieces of state information that need to be shared between +the System UI and some or all applications. */ |