You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+62-2Lines changed: 62 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -229,7 +229,7 @@ MyFirstThread::OnLoop() - Thread 3 - On CPU 0, Counter = 2
229
229
MyFirstThread::OnLoop() - Thread 2 - On CPU 1, Counter = 2
230
230
```
231
231
232
-
The explicit maximum number of *ESPresio*`Thread`s supported by the library is 256, however the *practical limit* depends entirely on the specifications of your microcontroller. It's almost certainly going to be considerably lower than 256!
232
+
The explicit maximum number of *ESPressio*`Thread`s supported by the library is 256, however the *practical limit* depends entirely on the specifications of your microcontroller. It's almost certainly going to be considerably lower than 256!
233
233
234
234
### The Thread Manager
235
235
In the previous example, you'll see that we manually called `Initialize()` on each instance of `MyFirstThread`.
@@ -254,4 +254,64 @@ void setup() {
254
254
Manager::Initialize();
255
255
}
256
256
```
257
-
Now, all three of our `MyFirstThread` instances will start exactly as they did before, but we didn't have to explicitly `Initialize()` each of them separately.
257
+
Now, all three of our `MyFirstThread` instances will start exactly as they did before, but we didn't have to explicitly `Initialize()` each of them separately.
258
+
259
+
### Automated Garbage Collection
260
+
It is quite common to have `Thread`s with non-permanent lifetimes, such as *Worker Threads* (less common with microcontrollers, but not unheard of).
261
+
262
+
*ESPressio* Threads provides a means of leveraging fully-automatic *Garbage Collection* for your `Thread`s once they've `Terminated`.
263
+
264
+
Let's modify our previous example to take advantage of it, and let's add some *finality* to `MyFirstThread` so that it will automatically `Terminate` when it has done its "work":
265
+
```cpp
266
+
classMyFirstThread : publicThread {
267
+
private:
268
+
int _counter = 0;
269
+
protected:
270
+
void OnInitialization() override {
271
+
// Anything we need to do here prior to the Thread's Loop sstarting
272
+
}
273
+
274
+
void OnLoop() override {
275
+
_counter++; // Increment the counter
276
+
277
+
// Let's display some information about our Thread...
278
+
Serial.printf("MyFirstThread::OnLoop() - Thread #%d - On CPU %d, Counter = %d", GetThreadID(), xPortGetCoreID(), _counter);
279
+
280
+
if (_counter == 10) {
281
+
Termiante(); // This will Terminate the Thread
282
+
}
283
+
284
+
delay(1000); // Let's let this Thread wait for 1 second before it loops around again
Okay, so our `MyFirstThread` class has been updated so that it will automatically `Terminate` when the `_counter` reaches `10`.
291
+
292
+
I've also added a public *Constructor* to expose the overloaded constructor on `Thread`, which provides the optional `freeOnTerminate` parameter we shall be using in a moment.
293
+
294
+
Let's modify the way we define the *Instances* of `MyFirstThread` so that we can leverage Automatic Garbage Collection:
295
+
```cpp
296
+
MyFirstThread* thread1, thread2, thread3;
297
+
298
+
void setup() {
299
+
Serial.begin(115200);
300
+
301
+
// Create our Threads (passing `true` to the constructor for "FreeOnTerminate")
302
+
thread1 = new MyFirstThread(true);
303
+
thread2 = new MyFirstThread(true);
304
+
thread3 = new MyFirstThread(true);
305
+
306
+
delay(500); // Small delay just so that the thread doesn't start before the Serial Monitor is ready
307
+
308
+
Manager::Initialize();
309
+
}
310
+
```
311
+
Now, when you run this program, each of the three instances of `MyFirstThread` will loop precisely 10 times, output their entries to the Serial console, then each of them will automatically `Terminate()`.
312
+
313
+
At that moment, the *Automatic Garbage Collector* will be awoken, and will take responsibility for purging the unwanted instances from our device's active memory.
314
+
315
+
>It is important to understand when it's appropriate to take advantage of Automatic Garbage Collection, and when you should manually manage the memory of your `Thread`s.
316
+
317
+
It's also good to know that the *Automatic Garbage Collector* is a "good citizen" and doesn't take up undue memory or clock cycles when it doesn't have any garbage to collect.
0 commit comments