Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch.embedded > #27876 > unrolled thread
| Started by | "gp.kiwi@gmail.com" <graeme.prentice@gmail.com> |
|---|---|
| First post | 2018-07-20 04:01 -0700 |
| Last post | 2018-08-01 12:28 -0700 |
| Articles | 20 on this page of 50 — 15 participants |
Back to article view | Back to comp.arch.embedded
C++ threads versus PThreads for embedded Linux on ARM micro "gp.kiwi@gmail.com" <graeme.prentice@gmail.com> - 2018-07-20 04:01 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-07-20 20:19 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro graeme.prentice@gmail.com - 2018-07-20 15:54 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Paul Rubin <no.email@nospam.invalid> - 2018-07-20 18:27 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro graeme.prentice@gmail.com - 2018-07-20 23:58 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-07-21 14:32 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro mac <acolvin@efunct.com> - 2018-07-26 19:37 +0000
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2018-07-21 21:48 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2018-07-23 09:58 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Les Cargill <lcargill99@comcast.com> - 2018-07-22 13:15 -0500
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-07-27 08:51 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro "gp.kiwi@gmail.com" <graeme.prentice@gmail.com> - 2018-07-27 14:53 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Paul Rubin <no.email@nospam.invalid> - 2018-07-27 15:23 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-07-30 09:08 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-07-31 09:21 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-07-31 09:13 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-07-31 15:16 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-01 07:53 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro pozz <pozzugno@gmail.com> - 2018-08-01 15:49 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro upsidedown@downunder.com - 2018-08-01 21:47 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-08-01 12:11 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-01 20:23 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 12:24 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro upsidedown@downunder.com - 2018-08-02 16:14 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 16:43 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-08-02 09:12 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-02 18:13 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 23:05 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-08-02 14:22 -0700
Re: C++ threads versus PThreads for embedded Linux on ARM micro Niklas Holsti <niklas.holsti@tidorum.invalid> - 2018-08-03 10:14 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-03 10:22 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-02 23:48 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro upsidedown@downunder.com - 2018-08-02 19:56 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-02 18:14 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 23:12 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-02 23:52 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-03 10:28 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-03 11:21 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-03 13:51 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro upsidedown@downunder.com - 2018-08-03 09:11 +0300
Re: C++ threads versus PThreads for embedded Linux on ARM micro George Neuner <gneuner2@comcast.net> - 2018-08-04 03:00 -0400
Re: C++ threads versus PThreads for embedded Linux on ARM micro Robert Wessel <robertwessel2@yahoo.com> - 2018-08-02 12:23 -0500
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 23:13 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro George Neuner <gneuner2@comcast.net> - 2018-08-04 03:08 -0400
Re: C++ threads versus PThreads for embedded Linux on ARM micro Robert Wessel <robertwessel2@yahoo.com> - 2018-08-02 12:23 -0500
Re: C++ threads versus PThreads for embedded Linux on ARM micro George Neuner <gneuner2@comcast.net> - 2018-08-02 14:15 -0400
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-02 19:21 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro David Brown <david.brown@hesbynett.no> - 2018-08-02 23:18 +0200
Re: C++ threads versus PThreads for embedded Linux on ARM micro Tom Gardner <spamjunk@blueyonder.co.uk> - 2018-08-03 00:02 +0100
Re: C++ threads versus PThreads for embedded Linux on ARM micro StateMachineCOM <statemachineguru@gmail.com> - 2018-08-01 12:28 -0700
Page 1 of 3 [1] 2 3 Next page →
| From | "gp.kiwi@gmail.com" <graeme.prentice@gmail.com> |
|---|---|
| Date | 2018-07-20 04:01 -0700 |
| Subject | C++ threads versus PThreads for embedded Linux on ARM micro |
| Message-ID | <ddc2da65-65a3-4307-b93b-5ad1cc62a418@googlegroups.com> |
We're starting an embedded Linux C++ project with an ARM micro and using GCC V7. Can anyone suggest pros and cons of using C++ Threads versus PThreads (Posix threads).
[toc] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-07-20 20:19 +0200 |
| Message-ID | <pit93d$dtv$1@dont-email.me> |
| In reply to | #27876 |
On 20/07/18 13:01, gp.kiwi@gmail.com wrote: > We're starting an embedded Linux C++ project with an ARM micro and using GCC V7. Can anyone suggest pros and cons of using C++ Threads versus PThreads (Posix threads). > C++ threads are always a wrapper around an underlying library. So if you are using C++ on Linux, the C++ threads /are/ pthreads. These are the points I can think of for preferring C++ threads: + You have a nice class/template library with C++ threads, instead of a C function interface. + You have have RAII classes for locks and other synchronisation objects. + You have consistency with other C++ thread systems. + Your compiler may understand that your code is threaded. - You need at least C++11 (but that has huge advantages anyway, compared to older C++). - It is marginally more fiddly if you need the underlying thread details for features not supported by the C++ thread library.
[toc] | [prev] | [next] | [standalone]
| From | graeme.prentice@gmail.com |
|---|---|
| Date | 2018-07-20 15:54 -0700 |
| Message-ID | <62f86a9d-b0fe-4368-9de7-f0b71ffc203d@googlegroups.com> |
| In reply to | #27877 |
On Saturday, July 21, 2018 at 6:19:31 AM UTC+12, David Brown wrote: > On 20/07/18 13:01, gp...@gmail.com wrote: > > We're starting an embedded Linux C++ project with an ARM micro and using GCC V7. Can anyone suggest pros and cons of using C++ Threads versus PThreads (Posix threads). > > > > C++ threads are always a wrapper around an underlying library. So if > you are using C++ on Linux, the C++ threads /are/ pthreads. These are > the points I can think of for preferring C++ threads: > > + You have a nice class/template library with C++ threads, instead of a > C function interface. > > + You have have RAII classes for locks and other synchronisation objects. > > + You have consistency with other C++ thread systems. > > + Your compiler may understand that your code is threaded. > > - You need at least C++11 (but that has huge advantages anyway, compared > to older C++). > > - It is marginally more fiddly if you need the underlying thread details > for features not supported by the C++ thread library. That's great, thanks.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2018-07-20 18:27 -0700 |
| Message-ID | <877elpgyxt.fsf@nightsong.com> |
| In reply to | #27878 |
graeme.prentice@gmail.com writes: > That's great, thanks. Also, ask yourself if you really need threads in the first place. Depending on what you're doing, you may be better off with multiple processes. That gets rid of a lot of lock and race hazards, and if the processes can communicate through sockets, that improves scalability by making it easier for you to distribute your program across multiple machines if you run out of cpu cores on your original machine.
[toc] | [prev] | [next] | [standalone]
| From | graeme.prentice@gmail.com |
|---|---|
| Date | 2018-07-20 23:58 -0700 |
| Message-ID | <734190e1-1761-4ee8-9774-b7a09903fa9b@googlegroups.com> |
| In reply to | #27879 |
On Saturday, July 21, 2018 at 1:28:02 PM UTC+12, Paul Rubin wrote: > > Also, ask yourself if you really need threads in the first place. > Depending on what you're doing, you may be better off with multiple > processes. That gets rid of a lot of lock and race hazards, and if the > processes can communicate through sockets, that improves scalability by > making it easier for you to distribute your program across multiple > machines if you run out of cpu cores on your original machine. Thanks for the suggestion. The micro is an ARM9 LPC3250 SOM (we're forced to use this at the moment) which I believe is single core (it's hard to find out for some reason) but it could easily change in future. Based on a previous project, race conditions and deadlocks are a major headache so I'm hoping the core data will be written to by one thread only, maybe with lock-free queues. The CPU data cache is 32KB and it's probably "write through". We would have to do some performance tests to see if multi-processes and sockets is viable.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-07-21 14:32 +0200 |
| Message-ID | <piv95r$je2$1@dont-email.me> |
| In reply to | #27880 |
On 21/07/18 08:58, graeme.prentice@gmail.com wrote: > On Saturday, July 21, 2018 at 1:28:02 PM UTC+12, Paul Rubin wrote: >> >> Also, ask yourself if you really need threads in the first place. >> Depending on what you're doing, you may be better off with multiple >> processes. There are certainly tasks that are better handled as multiple processes rather than multiple threads. (But note that it is not an either/or choice - often the best solution uses both.) >> That gets rid of a lot of lock and race hazards, No, it does not - it merely changes them. If your separate threads of execution need to synchronise, communicate, or agree about shared resources, then there is no theoretical difference about the types of hazards, races, or other such problems if you use multiple threads or multiple processes. The details change, and the types of synchronisation objects use can change, but they do no not go away. Some may be handled by the OS rather than the application, however - for example, a pipe between processes will let you communicate without worry about locks for the underlying shared data structure, at the cost of being a lot less efficient than shared memory in threads. Multiple processes have higher resource costs, and they make it a lot harder to use tools such as "-fsanitize=thread" to find problems. On the other hand, they make it easier to break the problem down into separate tasks that are handled independently and tested independently. That helps if you have different developers - or even different programming languages. >> and if the >> processes can communicate through sockets, that improves scalability by >> making it easier for you to distribute your program across multiple >> machines if you run out of cpu cores on your original machine. True. This can also be useful during development when you might have some of the bits running on your target system, and other bits running on your host computer (perhaps under a debugger). > > Thanks for the suggestion. The micro is an ARM9 LPC3250 SOM (we're > forced to use this at the moment) which I believe is single core (it's > hard to find out for some reason) but it could easily change in future. That doesn't matter for the choice of threads, processes or both. > Based on a previous project, race conditions and deadlocks are a major > headache so I'm hoping the core data will be written to by one thread > only, maybe with lock-free queues. The CPU data cache is 32KB and it's > probably "write through". We would have to do some performance tests to > see if multi-processes and sockets is viable. Multiple processes are slower than multiple threads, and sockets are much slower than in-process queues. But the sockets are more flexible. You might find you want an abstraction that can use either method as a backend, and change during different stages of development.
[toc] | [prev] | [next] | [standalone]
| From | mac <acolvin@efunct.com> |
|---|---|
| Date | 2018-07-26 19:37 +0000 |
| Message-ID | <1188747523.554326005.017098.acolvin-efunct.com@news.eternal-september.org> |
| In reply to | #27881 |
You can also communicate among processes through shared memory (e.g. mmap). To look at a other way, processes require explicit sharing, threads share implicitly. On an embedded system, the heavier cost of process switching may be important.
[toc] | [prev] | [next] | [standalone]
| From | Tauno Voipio <tauno.voipio@notused.fi.invalid> |
|---|---|
| Date | 2018-07-21 21:48 +0300 |
| Message-ID | <pivv5q$una$1@dont-email.me> |
| In reply to | #27880 |
On 21.7.18 09:58, graeme.prentice@gmail.com wrote: > Thanks for the suggestion. The micro is an ARM9 LPC3250 SOM (we're forced to use this at the moment) which I believe is single core (it's hard to find out for some reason) but it could easily change in future. Based on a previous project, race conditions and deadlocks are a major headache so I'm hoping the core data will be written to by one thread only, maybe with lock-free queues. The CPU data cache is 32KB and it's probably "write through". We would have to do some performance tests to see if multi-processes and sockets is viable. For number of cores on your system, if you have Linux running on the target, have a look at /proc/cpuinfo: tauno@pi2:~ $ cat /proc/cpuinfo processor : 0 model name : ARMv7 Processor rev 5 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc07 CPU revision : 5 processor : 1 model name : ARMv7 Processor rev 5 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc07 CPU revision : 5 processor : 2 model name : ARMv7 Processor rev 5 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc07 CPU revision : 5 processor : 3 model name : ARMv7 Processor rev 5 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc07 CPU revision : 5 Hardware : BCM2835 Revision : a01041 Serial : 0000000064d34ba1 --- The above is from a Raspberry Pi 2. -- -TV
[toc] | [prev] | [next] | [standalone]
| From | Rob Gaddi <rgaddi@highlandtechnology.invalid> |
|---|---|
| Date | 2018-07-23 09:58 -0700 |
| Message-ID | <pj51f6$r1k$1@dont-email.me> |
| In reply to | #27880 |
On 07/20/2018 11:58 PM, graeme.prentice@gmail.com wrote: > On Saturday, July 21, 2018 at 1:28:02 PM UTC+12, Paul Rubin wrote: >> >> Also, ask yourself if you really need threads in the first place. >> Depending on what you're doing, you may be better off with multiple >> processes. That gets rid of a lot of lock and race hazards, and if the >> processes can communicate through sockets, that improves scalability by >> making it easier for you to distribute your program across multiple >> machines if you run out of cpu cores on your original machine. > > Thanks for the suggestion. The micro is an ARM9 LPC3250 SOM (we're forced to use this at the moment) which I believe is single core (it's hard to find out for some reason) but it could easily change in future. Based on a previous project, race conditions and deadlocks are a major headache so I'm hoping the core data will be written to by one thread only, maybe with lock-free queues. The CPU data cache is 32KB and it's probably "write through". We would have to do some performance tests to see if multi-processes and sockets is viable. > 3250 is single-core. Happens to be a part we use a lot around here, although we always go bare-metal rather than running Linux. Cache is programmable through the page-table as to whether it's write-through or not. The reason you're having trouble determining much of this information is that NXP bought large chunks of that chip wholesale from ARM without anyone there actually understanding it. So the NXP documentation is spotty and occasionally wrong (let me tell you of our I2C-based woes). There's a document available directly from ARM, ARM DDI 0198E, that is specifically the ARM926EJ-S Technical Reference Manual. Getting into the details on the 3250 is nearly impossible without it. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix.
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2018-07-22 13:15 -0500 |
| Message-ID | <pj2hc7$5hr$1@dont-email.me> |
| In reply to | #27876 |
gp.kiwi@gmail.com wrote: > We're starting an embedded Linux C++ project with an ARM micro and > using GCC V7. Can anyone suggest pros and cons of using C++ Threads > versus PThreads (Posix threads). > I'd suggest thinking about a design for how you'd measure which works in context for you. If I run pthreads on a big Linux machine it'll be different from running them in a VM. Similarly, it'll be different on a RasPi 3 sized ARM computer. -- Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | StateMachineCOM <statemachineguru@gmail.com> |
|---|---|
| Date | 2018-07-27 08:51 -0700 |
| Message-ID | <b28cf52f-2a9e-4e6a-9f3f-8b9921c3a0c1@googlegroups.com> |
| In reply to | #27876 |
Traditional threads, whichever way you package them (as C++ threads, p-threads or any other thread library), typically correspond to the "shared-state concurrency and blocking" approach. This approach is known to be problematic, and many experts in concurrent programming recommend to drastically limit both sharing and blocking according to the following three best practices: 1. Keep data isolated and bound to threads. Threads should hide (encapsulate) their private data and other resources, and not share them with the rest of the system. 2. Communicate among threads asynchronously via messages (event objects). Using asynchronous events keeps the threads running truly independently, without any further blocking on each other. 3. Threads should spend their lifetime responding to incoming events, so their mainline should consist of an event-loop that handles events one at a time (to completion), thus avoiding any concurrency hazards within a thread itself. The set of these best practices are collectively known as the Active Object design pattern (a.k.a. Actor). While this pattern can be applied manually on top of a traditional threads, a better way is to use an Active Object framework. The main difference is that when you use "naked" threads, you write the main body of the application (such as the thread routines for all your tasks) and you call various thread-library services (e.g., a semaphore or a time delay). When you use a framework, you reuse the overall architecture and write the code that it calls. This leads to inversion of control, which allows the framework to automatically enforce the best practices of concurrent programming. In contrast, a "naked" threads let you do anything and offer no help or automation for the best practices.
[toc] | [prev] | [next] | [standalone]
| From | "gp.kiwi@gmail.com" <graeme.prentice@gmail.com> |
|---|---|
| Date | 2018-07-27 14:53 -0700 |
| Message-ID | <8490b5e0-bf86-413c-866e-8a10a3d87466@googlegroups.com> |
| In reply to | #27895 |
Thanks. What is an "event object"? What is the best way to pass data asynchronously using a queue, on Linux? I've read that lock-free data structures are easy to get wrong and best avoided and that the C++ thread library doesn't have any lock free data structures - mainly because there's too many variations to have a generalized data structure. Can we use the "libcds" library and be confident that it will work correctly? https://github.com/khizmax/libcds On Saturday, July 28, 2018 at 3:52:02 AM UTC+12, StateMachineCOM wrote: > Traditional threads, whichever way you package them (as C++ threads, p-threads or any other thread library), typically correspond to the "shared-state concurrency and blocking" approach. This approach is known to be problematic, and many experts in concurrent programming recommend to drastically limit both sharing and blocking according to the following three best practices: [snip]
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2018-07-27 15:23 -0700 |
| Message-ID | <877elge2t0.fsf@nightsong.com> |
| In reply to | #27896 |
"gp.kiwi@gmail.com" <graeme.prentice@gmail.com> writes: > Thanks. What is an "event object"? Just a message that you pass from one thread to another. > What is the best way to pass data asynchronously using a queue, on > Linux? I'd probably just use std::deque with a lock. You might look at seastar-project.org for some inspiration.
[toc] | [prev] | [next] | [standalone]
| From | StateMachineCOM <statemachineguru@gmail.com> |
|---|---|
| Date | 2018-07-30 09:08 -0700 |
| Message-ID | <d68320e5-08d8-4e2b-9a00-21fdde1dd9de@googlegroups.com> |
| In reply to | #27896 |
On Friday, July 27, 2018 at 5:53:28 PM UTC-4, gp....@gmail.com wrote: > What is an "event object"? What is the best way to pass data asynchronously using a queue, on Linux? I can tell you how this is done in the QP/C++ framework, which I've designed and refined for almost two decades now. But before I can get to the technical, I need to make full disclosure that QP is a dual-licensed (open-source/commercial) product of my company (see https://www.state-machine.com), so I do have a commercial interest in promoting it. So, now going back to your question, "event objects" are messages that threads send to each other via event queues. But a naive implementation of copying messages to and from the queues is expensive and hurts real-time performance. So, in the QP framework, the events are allocated from fixed-size pools and only pointers to events are kept in the event queues. The framework maintains the copy-by-value semantics as much as possible, while event objects are really shared under the hood. The framework also automatically recycles events that are processed. Specifically to the POSIX port of QP/C++, which has been available for over 15 years now, each active object runs in its own p-thread. These threads are organized as an event-loop (according to the best practice I listed in my previous thread), so they block only in one place--when the event queue is empty. The queue uses internally a p-thread mutex and a condition variable to implement blocking on an event queue and signaling the queue. But the application programmer does not need to know any of it, because the main point is that the framework does the heavy lifting of thread-safe asynchronous event exchange. The application threads (active objects) only process the events one at a time (to completion), but they don't need to worry about any low-level mechanisms like mutexs or condition variables. The design also allows you to avoid sharing of anything (except events) among the threads, which is another best-practice of concurrent programming. This means that you don't need to use any synchronization objects. In this sense, the RAII benefits of synchronization mechanisms in the C++ threads don't matter. There is of course much more to active object framework like QP/C++ to capture here. For example, the framework supports Hierarchical State Machines to implement the internal behavior of active objects. There is also a free modeling tool (QM), with which you can design your HSMs graphically and generate production-code automatically. But all of this requires a paradigm shift from the traditional sequential-programming with blocking to event-driven programming without blocking or sharing. To learn more, you might read about the key concepts here: https://www.state-machine.com/doc/concepts Miro Samek state-machine.com
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-07-31 09:21 +0200 |
| Message-ID | <pjp2l1$4c7$1@dont-email.me> |
| In reply to | #27896 |
On 27/07/18 23:53, gp.kiwi@gmail.com wrote: > Thanks. What is an "event object"? What is the best way to pass > data asynchronously using a queue, on Linux? I've read that > lock-free data structures are easy to get wrong and best avoided and > that the C++ thread library doesn't have any lock free data > structures - mainly because there's too many variations to have a > generalized data structure. Lock-free data structures can range from very simple to very difficult, and there can be huge differences depending on the details of the structure. A single-writer, single-reader fixed size queue is /easy/ - it's just two atomic counters for "head" and "tail" and an array, with a little care about memory ordering. For single core embedded processors, it's usually sufficient to just use "volatile" - for bigger systems, C++11 or C11 atomics handle the details. On the other hand, a queue that can have variable size, and more than one reader or writer, quickly gets really complicated to handle lock-free, and often it is much simpler, safer and cheaper to use a lock. On the third hand, if you have multiple cores you might want lock-free again for scalability. There is no simple answer here, and much depends on the details of exactly what you are wanting. As long as you ask general questions, you'll only get general answers. > > Can we use the "libcds" library and be confident that it will work > correctly? > > https://github.com/khizmax/libcds > > > On Saturday, July 28, 2018 at 3:52:02 AM UTC+12, StateMachineCOM > wrote: >> Traditional threads, whichever way you package them (as C++ >> threads, p-threads or any other thread library), typically >> correspond to the "shared-state concurrency and blocking" approach. >> This approach is known to be problematic, and many experts in >> concurrent programming recommend to drastically limit both sharing >> and blocking according to the following three best practices: > [snip] >
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-07-31 09:13 +0200 |
| Message-ID | <pjp272$1uc$1@dont-email.me> |
| In reply to | #27895 |
On 27/07/18 17:51, StateMachineCOM wrote: > Traditional threads, whichever way you package them (as C++ threads, > p-threads or any other thread library), typically correspond to the > "shared-state concurrency and blocking" approach. This approach is > known to be problematic, and many experts in concurrent programming > recommend to drastically limit both sharing and blocking according to > the following three best practices: > > 1. Keep data isolated and bound to threads. Threads should hide > (encapsulate) their private data and other resources, and not share > them with the rest of the system. Encapsulation is always a good principle, but don't take it too far. If two parts of the system need to share data of significant size, then you want shared data, not "messages" or other synchronisation mechanisms. (You use the messages or other synchronisation to communicate metadata - such as who owns the real data space at any given time - but not the data itself.) > > 2. Communicate among threads asynchronously via messages (event > objects). Using asynchronous events keeps the threads running truly > independently, without any further blocking on each other. > Blocking is fine with threads. If you have a single core cpu - or more threads than cores - then blocking is often more efficient than attempting to continue. After all, if thread A is asking thread B to do something (via a message, actor call, or whatever) then thread B can't get started in doing the work A wants until A has taken a break. It's cheaper to have a voluntary break (yield, or blocking call) than to wait for a scheduling change. So use blocking calls whenever they fit naturally in the progression of the code - and non-blocking calls whenever /that/ is the more natural fit. Don't make the mistake of thinking that one is inherently "better" or necessarily more efficient - /measure/ the /real/ effects if efficiency is vital. > 3. Threads should spend their lifetime responding to incoming events, > so their mainline should consist of an event-loop that handles events > one at a time (to completion), thus avoiding any concurrency hazards > within a thread itself. > > The set of these best practices are collectively known as the Active > Object design pattern (a.k.a. Actor). While this pattern can be > applied manually on top of a traditional threads, a better way is to > use an Active Object framework. Actor designs can certainly have their advantages - equally certainly, they are not the best design for all uses. Whenever someone says "this is the best way to do it", it's unlikely to be that simple - and whenever they say so without knowing exact details of the problem at hand, they are almost certainly wrong. > > The main difference is that when you use "naked" threads, you write > the main body of the application (such as the thread routines for all > your tasks) and you call various thread-library services (e.g., a > semaphore or a time delay). When you use a framework, you reuse the > overall architecture and write the code that it calls. This leads to > inversion of control, which allows the framework to automatically > enforce the best practices of concurrent programming. In contrast, a > "naked" threads let you do anything and offer no help or automation > for the best practices. >
[toc] | [prev] | [next] | [standalone]
| From | StateMachineCOM <statemachineguru@gmail.com> |
|---|---|
| Date | 2018-07-31 15:16 -0700 |
| Message-ID | <4c2a996d-d88f-4954-a2af-e4e4663c6b35@googlegroups.com> |
| In reply to | #27899 |
@David Brown: Absolutely, if you stick to the traditional sequential programming paradigm with shared-state concurrency and blocking threads, the three best practices I listed in my previous post can all be questioned, relaxed, and ultimately dismissed.
That's because they represent a different, event-driven ("reactive") programming paradigm. The distinction is important, because the two programming paradigms do NOT mix well, certainly not inside the same thread. So it is important to always realize which paradigm you are using in which thread, to avoid confusion and mixing the two.
To back up this point, I'd like to recommend the article "Managing Concurrency in Complex Embedded Systems" by David Cummings (http://www.kellytechnologygroup.com/main/concurrent-embedded-systems-website.pdf ). The author presents general guiding principles of structuring threads, which he found particularly useful and which he applied in the NASA Mars rovers and other mission-critical systems. The paper starts with the description of the general thread structure, which can be immediately recognized as the event-loop. The bulk of the paper then focuses on discussing several scenarios in which designers might be tempted to apply thread BLOCKING, followed by explanations why blocking is always a BAD idea. Again, I repeat, that this conclusion applies to the "event-driven" thread structure, which the author started with.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-08-01 07:53 +0200 |
| Message-ID | <pjrhrv$ac1$1@dont-email.me> |
| In reply to | #27901 |
On 01/08/18 00:16, StateMachineCOM wrote:
> @David Brown: Absolutely, if you stick to the traditional sequential programming paradigm with shared-state concurrency and blocking threads, the three best practices I listed in my previous post can all be questioned, relaxed, and ultimately dismissed.
>
> That's because they represent a different, event-driven ("reactive") programming paradigm. The distinction is important, because the two programming paradigms do NOT mix well, certainly not inside the same thread. So it is important to always realize which paradigm you are using in which thread, to avoid confusion and mixing the two.
>
> To back up this point, I'd like to recommend the article "Managing Concurrency in Complex Embedded Systems" by David Cummings (http://www.kellytechnologygroup.com/main/concurrent-embedded-systems-website.pdf ). The author presents general guiding principles of structuring threads, which he found particularly useful and which he applied in the NASA Mars rovers and other mission-critical systems. The paper starts with the description of the general thread structure, which can be immediately recognized as the event-loop. The bulk of the paper then focuses on discussing several scenarios in which designers might be tempted to apply thread BLOCKING, followed by explanations why blocking is always a BAD idea. Again, I repeat, that this conclusion applies to the "event-driven" thread structure, which the author started with.
>
I haven't read the link yet (I will do so), but I do agree that blocking
is a very bad idea in an event-driven thread.
[toc] | [prev] | [next] | [standalone]
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2018-08-01 15:49 +0200 |
| Message-ID | <pjsdpk$c17$1@dont-email.me> |
| In reply to | #27901 |
Il 01/08/2018 00:16, StateMachineCOM ha scritto:
> @David Brown: Absolutely, if you stick to the traditional sequential programming paradigm with shared-state concurrency and blocking threads, the three best practices I listed in my previous post can all be questioned, relaxed, and ultimately dismissed.
>
> That's because they represent a different, event-driven ("reactive") programming paradigm. The distinction is important, because the two programming paradigms do NOT mix well, certainly not inside the same thread. So it is important to always realize which paradigm you are using in which thread, to avoid confusion and mixing the two.
>
> To back up this point, I'd like to recommend the article "Managing Concurrency in Complex Embedded Systems" by David Cummings (http://www.kellytechnologygroup.com/main/concurrent-embedded-systems-website.pdf ).
Thanks for this reference... it is a very *very* instructive material.
[toc] | [prev] | [next] | [standalone]
| From | upsidedown@downunder.com |
|---|---|
| Date | 2018-08-01 21:47 +0300 |
| Message-ID | <3kv3md9lvenno2jabfamrccu2glr6j877h@4ax.com> |
| In reply to | #27901 |
On Tue, 31 Jul 2018 15:16:07 -0700 (PDT), StateMachineCOM
<statemachineguru@gmail.com> wrote:
>@David Brown: Absolutely, if you stick to the traditional sequential programming paradigm with shared-state concurrency and blocking threads, the three best practices I listed in my previous post can all be questioned, relaxed, and ultimately dismissed.
>
>That's because they represent a different, event-driven ("reactive") programming paradigm. The distinction is important, because the two programming paradigms do NOT mix well, certainly not inside the same thread. So it is important to always realize which paradigm you are using in which thread, to avoid confusion and mixing the two.
>
>To back up this point, I'd like to recommend the article "Managing Concurrency in Complex Embedded Systems" by David Cummings (http://www.kellytechnologygroup.com/main/concurrent-embedded-systems-website.pdf ). The author presents general guiding principles of structuring threads, which he found particularly useful and which he applied in the NASA Mars rovers and other mission-critical systems. The paper starts with the description of the general thread structure, which can be immediately recognized as the event-loop. The bulk of the paper then focuses on discussing several scenarios in which designers might be tempted to apply thread BLOCKING, followed by explanations why blocking is always a BAD idea. Again, I repeat, that this conclusion applies to the "event-driven" thread structure, which the author started with.
It seems Cummings has reinvented the wheel :-).
Those principles were used already in the 1970's to implement real
time systems under RSX-11 on PDP-11. Later on these principles were
also used on real time systems under RMX-80 for 8080 and similar
kernels.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.arch.embedded
csiph-web