# Keep \`delay\` based approach while doing things concurrently with \`proto\_activities\`

**URL:** <https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012>\
**Category:** Libraries\
**Created:** [October 4, 2024, 2:58pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012 "2024-10-04T14:58:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 4, 2024, 2:58pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/1 "2024-10-04T14:58:36Z")

</div>

New developers start using `delay` but find out soon, that to do multiple things at once, a different and more complex approach is needed like using `millis` to measure elapsed time to do part of the work when ready as well as state-machines to stitch all these parts together again.

[`proto_activities`](https://github.com/frameworklabs/proto_activities) is a header only library which simplifies these tasks by concurrently running activities which can behave like separate `loops` allowing `delays` in each of them. With the help of preemption constructs, complex state-flow can be achieved in a modular and deterministic way.

A running `proto_activities` example demonstrating the approach can be found [here](https://wokwi.com/projects/385178429273730049).

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [October 4, 2024, 6:26pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/2 "2024-10-04T18:26:39Z")

</div>

This forum has a tutorial on multiple things at once.

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 8, 2024, 9:22pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/3 "2024-10-08T21:22:55Z")

</div>

Here is. how the [StateChangeDetection tutorial](https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/) would look like with `proto_activities`:  
[wokwi](https://wokwi.com/projects/411117317662580737).

---

<div class="post-metadata">

**Author:** ![outbackhut](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/outbackhut/32/1099892_2.png) [@outbackhut](https://forum.arduino.cc/u/outbackhut)\
**Post date:** [October 8, 2024, 9:42pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/4 "2024-10-08T21:42:57Z")

</div>

> [@frameworklabs](#):
>
> [`proto_activities`](https://github.com/frameworklabs/proto_activities) is a header only library which simplifies these tasks by concurrently running activities which can behave like separate `loops` allowing `delays` in each of them.

Can you explain why we would want to do this? As I see it, there are far better ways of doing this, as @sonofcy said.

What makes your library better? What does it do that the other normal way doesn't?

Not picking on you, asking productive questions here.

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [October 8, 2024, 10:17pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/5 "2024-10-08T22:17:00Z")

</div>

Define concurrent. I have yet in 50 years to see any cpu run more than 1 thing at a time. That means in order to pretend to do more than one thing requires fast task switching based on some sort of priority scheme. I know of two (pre-emptive and co-operative), if you have invented a third, subject it to peer review.

---

<div class="post-metadata">

**Author:** ![DaveX](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/davex/32/751443_2.png) [@DaveX](https://forum.arduino.cc/u/DaveX)\
**Post date:** [October 9, 2024, 1:16am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/6 "2024-10-09T01:16:49Z")

</div>

How does it compare with

> **[GitHub - DrDiettrich/ALib0: Arduino library for button handling and parallel...](https://github.com/DrDiettrich/ALib0)**
>
> Arduino library for button handling and parallel execution.

and

> [@Running multiple waiting functions simultanously](https://forum.arduino.cc/t/running-multiple-waiting-functions-simultanously/975765):
>
> CAN YOU SOLVE THIS CHALLENGE? I have been trying for a while to run SIMULTANOUSLY two or more functions, each function having multiple internal "waiting conditions". The waiting conditions are not important: they could be waiting for an external input, an internal event, etc. Since the most common waiting condition is time, I would like to write two functions that both wait for time internally, and make them run simultanously. For example: Say the first function sends an arbitrary str…

and

> [@Timing utility: an alternative to delay()](https://forum.arduino.cc/t/timing-utility-an-alternative-to-delay/965542):
>
> A small timing utility: can be a non blocking replacement for delay(). The need: execute a function on a timed basis, without blocking the processor with delay(). Independant of the time taken by other running processes. Example of use: flash a led at 3 hertz rate while flashing a second led at 11 hertz, a third at 0,75 Hz, etc. The two main functions: startTimer() and checkTimer. Have fun! void setup() { Serial.begin(9600); } //-------------------------------------------------- int tickP…

and the otehr things in

> [@Is there a non blocking delay that's as easy to use as the built in delay function?](https://forum.arduino.cc/t/is-there-a-non-blocking-delay-thats-as-easy-to-use-as-the-built-in-delay-function/1195423):
>
> i keep wondering why the built in standard 'delay ();' function hasn't been changed to a non blocking delay function. i can see when searching that there are many libraries / functions offered with non blocking delays, and i can vaguely remember a way of using the milli's function. But they all seem to need quite a few bits of code to use, I'd have thought it may be easier for beginners (and people like me who forget stuff) to be able to simply type something like : 'nonBlockingDelay (1000); …

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 9, 2024, 9:42am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/7 "2024-10-09T09:42:09Z")

</div>

I think it helps you to write code which is easier to understand, maintain and reuse.

This is achieved by explicitly declaring concurrency and preemption aspects which are otherwise done in a more ad hoc manner.

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 9, 2024, 9:48am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/8 "2024-10-09T09:48:01Z")

</div>

To make it short - this lib uses a co-operative approach to concurrency.

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 9, 2024, 9:55am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/9 "2024-10-09T09:55:33Z")

</div>

`proto_activities` is based on the same protothreads approach like some other libs (like ALib0) but is special in that it does not require the use of static variables.

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [October 9, 2024, 12:32pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/10 "2024-10-09T12:32:46Z")

</div>

Not something I would be interested in then, I held the world record for fastest transaction processor at one time and that only happened due to pre-emptive tasking.

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [October 9, 2024, 3:35pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/11 "2024-10-09T15:35:22Z")

</div>

> [@sonofcy](#):
>
> I have yet in 50 years to see any cpu run more than 1 thing at a time

Intel's hyperthreading does that. It can run multiple threads of execution on a single core.

And depending on how you look at it, it's possible to run `delay()` (or a protothread-aware version of it) "concurrently" on multiple threads since it's not really running any CPU code while it waits. In other words, they all run concurrently in wall time rather than in CPU time.

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [October 9, 2024, 5:54pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/12 "2024-10-09T17:54:49Z")

</div>

They just renamed things and/or redefined things. My training started on discrete hardware, then micro code, then OS so I have seen all the underlying code and know how it works. It's still a binary world no matter what you label it as.

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [October 9, 2024, 6:23pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/13 "2024-10-09T18:23:25Z")

</div>

This parallels the talking heads of cold fusion quackery of the 70s, 80s and 90s. More snake oil abstraction layers.

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [October 9, 2024, 6:58pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/14 "2024-10-09T18:58:02Z")

</div>

I've played with protothreads in the past, and the OP's library is a layer around it to make it easier to pass around context. In that way it appears to do what it's supposed to.

Then again, Rob Pike (of Go fame) pointed out the distinction between concurrency and parallelism (see [Concurrency is not Parallelism](https://go.dev/talks/2012/waza.slide)). You can have processes (tasks, threads, whatever) that don't run simultaneously but are still _concurrent_. The point of concurrency is to decompose a problem into smaller independent processes that can run on their own (whether in parallel or not). From this standpoint, OP's library (and many of the other solutions offered) seems to fit the bill.

After using various threading systems (pthreads, C++ threads, and my own cooperative and preemptive threading libraries), I've fairly recently started using Go and its goroutines (and channels for communicating between them). It's a big shift in thinking about concurrency, and it really simplifies breaking down a program into concurrent processes. I think it would be interesting to bring that system to Arduino, rather than implementing yet another threading system. Or just use Go on Arduino ([https://tinygo.org/](https://tinygo.org/)). 😃

---

<div class="post-metadata">

**Author:** ![outbackhut](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/outbackhut/32/1099892_2.png) [@outbackhut](https://forum.arduino.cc/u/outbackhut)\
**Post date:** [October 10, 2024, 1:51am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/15 "2024-10-10T01:51:33Z")

</div>

> [@christop](#):
>
> Intel's hyperthreading does that. It can run multiple threads of execution on a single core.

_"Hyper-Threading doesn't mean a core is truly doing two things simultaneously in the same sense as having two physical cores. Instead, it's better understood as optimizing resource use by quickly switching between two tasks or threads when one would otherwise be idle._

_In a traditional single-threaded core, there are moments when parts of the CPU are waiting, for instance, for data to be retrieved from memory. Hyper-Threading takes advantage of these idle moments by scheduling instructions from a second thread to keep the core busy. So, while it's not "literally" performing two tasks at the exact same moment in time (like two physical cores would), it's effectively multitasking by keeping more of the core's resources in use."_

Also this:  
[How does my computer do several things at once?](https://tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/multitasking.html#:~:text=It%20doesn't%2C%20actually.,This%20is%20called%20timesharing).

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [October 10, 2024, 6:41pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/16 "2024-10-10T18:41:09Z")

</div>

My understanding is that Hyper-Threading is basically an extension of concepts like pipelining and out-of-order execution (OoOE). If part of a core is unused at any moment, some part of an instruction from a thread can be executed in that part of the core _at the same time_ (i.e., during the same clock cycle) as part of an instruction from another thread is running on a different part of the core.

Just as a single core can run two instructions like `movl $1, %eax` and `movl $2, %ebx` at the same time (not just "quickly switching between" them as your quote implies), a single core could run two instructions from two different threads at the same time.

I haven't looked at the technology too closely, but I imagine hyper-threading is basically the same as OoOE but with each instruction (or micro-instruction) in the pipeline tagged with the thread it belongs to so the core can execute it with the thread's context (set of registers, status flags, etc.).

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [October 10, 2024, 6:53pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/17 "2024-10-10T18:53:52Z")

</div>

> [@outbackhut](#):
>
> Also this:  
> [How does my computer do several things at once?](https://tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/multitasking.html#:~:text=It%20doesn't%2C%20actually.,This%20is%20called%20timesharing).

This is referring to multi-tasking on a classic single-threaded CPU. It also applies to Hyper-threaded or multiple cores when more than one thread is running on a single physical or logical core, though kernels strive to balance threads across all cores to avoid that. IIRC, FreeBSD, once per second, moves some threads from the core with the most running threads to the core with the fewest running threads; this eventually balances them.

Edit: FreeBSD's ULE scheduler actually balances threads between two cores _twice_ per second:

> Twice per second the sched\_balance() routine picks the most-loaded and least-loaded processors in the system and equalizes their run queues

(From [https://dl.acm.org/doi/fullHtml/10.1145/1035594.1035622#:~:text=Twice%20per%20second%20the%20sched\_balance()%20routine%20picks%20the%20most-loaded%20and%20least-loaded%20processors%20in%20the%20system%20and%20equalizes%20their%20run%20queues](https://dl.acm.org/doi/fullHtml/10.1145/1035594.1035622#:~:text=Twice%20per%20second%20the%20sched_balance()%20routine%20picks%20the%20most%2Dloaded%20and%20least%2Dloaded%20processors%20in%20the%20system%20and%20equalizes%20their%20run%20queues))

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 13, 2024, 9:55pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/18 "2024-10-13T21:55:29Z")

</div>

Go looks interesting but I would like to see more language support for structured concurrency.

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/frameworklabs/32/1107971_2.png) [@frameworklabs](https://forum.arduino.cc/u/frameworklabs)\
**Post date:** [October 28, 2024, 9:18am UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/19 "2024-10-28T09:18:57Z")

</div>

[Here](https://forum.arduino.cc/t/making-an-output-go-high-while-another-sequence-is-running/1315483/13) is another example of `proto_activities` which shows, how `goto`-like state machines can be replaced by structured programming, leading to simpler to understand and easier to maintain programs.

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [October 28, 2024, 5:37pm UTC](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012/20 "2024-10-28T17:37:14Z")

</div>

> [@frameworklabs](#):
>
> language support for structured concurrency

One of Go's philosophies is to keep the language itself as simple as possible while still being useful and expressive. Many features have been proposed to be added to the core language, but most are rejected if they do little but add some syntactic sugar.

Structured concurrency would likely be considered "syntactic sugar" since packages like `sync` already provide most (if not all) of your structured concurrency needs (e.g., waiting for a group of goroutines to finish).

[Next page](https://forum.arduino.cc/t/keep-delay-based-approach-while-doing-things-concurrently-with-proto-activities/1308012.md?page=2)
