summaryrefslogtreecommitdiffstats
path: root/doc/singlevsmultiprocess.qdoc
blob: 0fffe16811abb68d263b4e97eff06dee10b6c24d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Luxoft Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
** Licensees holding valid commercial Qt Automotive Suite licenses may use
** this file in accordance with the commercial license agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and The Qt Company.  For
** licensing terms and conditions see https://www.qt.io/terms-conditions.
** For further information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!

\page singlevsmultiprocess.html
\title Single-Process vs. Multi-Process Mode

The application manager can run the System UI and QML applications in two different modes:

\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 \c qml or \c 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 allows for:

\list
   \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

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.

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 Configuration

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

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.

Similarly, a custom \c pluginPath as part of \c info.yaml behaves differently in single-process
mode, than in multi-process mode. When a new process starts in multi-process mode, the new \c
pluginPath can be added to Qt very early on, before most systems are initialized. This ensures that
when a QPluginLoader is used, the \c pluginPath is correct. In comparison, with single-process
mode, we need to add an additional \c pluginPath to the QApplication already running. Whether this
change has any effect depends on how the plugin is loaded: if the \c pluginPath is reevaluated
whenever a new plugin needs to be loaded.

\note In single-process mode, some configuration options have no effect, such as: \c quicklaunch,
      \c quicklaunchQml, \c crashAction, and so on.


\section1 Build and Runtime Options

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.

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 Application Lifetime

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

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; 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.
    \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; but this is not the case in
    single-process mode.
\endlist


\section1 Resource Consumption

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.

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
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, 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. 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 Support for Single-Process and Multi-Procecss Mode in One Application

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.

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.

*/