File: chapter-multi-threaded-programs.html

package info (click to toggle)
gtkmm-documentation 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,772 kB
  • sloc: cpp: 15,541; javascript: 1,208; makefile: 1,080; python: 401; xml: 106; perl: 67; sh: 8
file content (203 lines) | stat: -rw-r--r-- 8,807 bytes parent folder | download
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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="highlight.min.css">
<script src="highlight.min.js"></script><script>
      hljs.configure({languages: ['cpp']});
      hljs.highlightAll();
    </script><title>Chapter 29. Multi-threaded programs</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="Programming with gtkmm 4">
<link rel="up" href="index.html" title="Programming with gtkmm 4">
<link rel="prev" href="sec-custom-css-names.html" title="Custom CSS Names">
<link rel="next" href="sec-using-glib-dispatcher.html" title="Using Glib::Dispatcher">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Chapter 29. Multi-threaded programs</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="sec-custom-css-names.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="sec-using-glib-dispatcher.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="chapter-multi-threaded-programs"></a>Chapter 29. Multi-threaded programs</h1></div></div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<ul class="toc">
<li><span class="section"><a href="chapter-multi-threaded-programs.html#sec-the-constraints">The constraints</a></span></li>
<li><span class="section"><a href="sec-using-glib-dispatcher.html">Using Glib::Dispatcher</a></span></li>
<li><span class="section"><a href="sec-multithread-example.html">Example</a></span></li>
</ul>
</div>


<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="sec-the-constraints"></a>The constraints</h2></div></div></div>


<p>
Care is required when writing programs based on <span class="application">gtkmm</span> using
multiple threads of execution, arising from the fact that
<span class="application">libsigc++</span>, and in particular
<code class="classname">sigc::trackable</code>, are not thread-safe. That's
because none of the complex interactions that occur behind the scenes
when using <span class="application">libsigc++</span> are protected by a
mutex or other means of synchronization.
<a href="#ftn.id7073" class="footnote" name="id7073"><sup class="footnote">[1]</sup></a>
</p>

<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="the-rules"></a>The rules</h3></div></div></div>


<p>
This requires a number of rules to be observed when writing
multi-threaded programs using <span class="application">gtkmm</span>. These are set out below, but
one point to note is that extra care is required when deriving classes
from <code class="classname">sigc::trackable</code>, because the effects are
unintuitive (see particularly points 4 and 5 below).
</p>

<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
<p>
Use <code class="classname">Glib::Dispatcher</code> to invoke <span class="application">gtkmm</span> functions
from worker threads (this is dealt with in more detail in the next
section).
</p>
</li>
<li class="listitem">
<p>
A <code class="classname">sigc::signal</code> object should be regarded as
owned by the thread which created it. Only that thread should connect
a <code class="classname">sigc::slot</code> object to the signal object, and
only that thread should <code class="methodname">emit()</code> or call
<code class="methodname">operator()()</code> on the signal, or null any
connected <code class="classname">sigc::slot</code> object. It follows
(amongst other things) that any signal object provided by a <span class="application">gtkmm</span>
widget should only be operated on in the main GUI thread and any
object deriving from <code class="classname">sigc::trackable</code> having its
non-static methods referenced by slots connected to the signal object
should only be destroyed in that thread.
</p>
</li>
<li class="listitem">
<p>
Any <code class="classname">sigc::connection</code> object should be regarded
as owned by the thread in which the method returning the
<code class="classname">sigc::connection</code> object was called. Only that
thread should call <code class="classname">sigc::connection</code> methods on
the object.
</p>
</li>
<li class="listitem">
<p>
A <code class="classname">sigc::slot</code> object created by a call to
<code class="function">sigc::mem_fun()</code> which references a method of a
class deriving from <code class="classname">sigc::trackable</code> should
never be copied to another thread, nor destroyed by a different thread
than the one which created it.
</p>
</li>
<li class="listitem">
<p>
If a particular class object derives from
<code class="classname">sigc::trackable</code>, only one thread should create
<code class="classname">sigc::slot</code> objects representing any of the
class's non-static methods by calling
<code class="function">sigc::mem_fun()</code>. The first thread to create such
a slot should be regarded as owning the relevant object for the
purpose of creating further slots referencing <span class="emphasis"><em>any</em></span>
of its non-static methods using that function, or nulling those slots
by disconnecting them or destroying the trackable object.
</p>
</li>
<li class="listitem">
<p>
Although <span class="application">glib</span> is itself thread-safe, any
<span class="application">glibmm</span> wrappers which use
<span class="application">libsigc++</span> will not be. So for example, only
the thread in which a main loop runs should call
<code class="methodname">Glib::SignalIdle::connect()</code>,
<code class="methodname">Glib::SignalIO::connect()</code>,
<code class="methodname">Glib::SignalTimeout::connect()</code>,
<code class="methodname">Glib::SignalTimeout::connect_seconds</code>
for that main loop, or manipulate any
<code class="classname">sigc::connection</code> object returned by them.
</p>
<p>
The connect*_once() variants,
<code class="methodname">Glib::SignalIdle::connect_once()</code>,
<code class="methodname">Glib::SignalTimeout::connect_once()</code>,
<code class="methodname">Glib::SignalTimeout::connect_seconds_once()</code>,
are thread-safe for any case where the slot is not created by a call to
<code class="function">sigc::mem_fun()</code> which represents a method of a class
deriving from <code class="classname">sigc::trackable</code>.
</p>
</li>
</ol></div>

</div>

</div>





<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.id7073" class="footnote">
<p><a href="#id7073" class="para"><sup class="para">[1] </sup></a>
These interactions arise from the fact that, amongst other things, a
class inheriting from <code class="classname">sigc::trackable</code> will, via
that inheritance, have a <code class="classname">std::list</code> object
keeping track of slots created by calls to
<code class="function">sigc::mem_fun()</code> representing any of its
non-static methods (more particularly it keeps a list of callbacks
which will null the connected slots on its destruction). Each
<code class="classname">sigc::slot</code> object also keeps, via
<code class="classname">sigc::slot_rep</code>, its own
<code class="classname">sigc::trackable</code> object to track any
<code class="classname">sigc::connection</code> objects which it needs to
inform about its demise, and also has a function to deregister itself
from any <code class="classname">sigc::trackable</code> on disconnection or
destruction. <code class="classname">sigc::signal</code> objects also keep
lists of slots, which will be updated by a call to their
<code class="methodname">connect()</code> method or calls to any
<code class="classname">sigc::connection</code> object relating to such a
connection.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="sec-custom-css-names.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="sec-using-glib-dispatcher.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Custom CSS Names </td>
<td width="20%" align="center"><a accesskey="h" href="index.html"><img src="icons/home.png" alt="Home"></a></td>
<td width="40%" align="right" valign="top"> Using Glib::Dispatcher</td>
</tr>
</table>
</div>
</body>
</html>