std::thread/mutex vs arp::thread/mutex
In the CPP guide it states:
"Never use std::mutex
in a real-time C++ program. If mutexes are required, use Arp::Mutex
."
Is there an explanation for this? My understanding is that in real-time systems you have to return control flow within a time frame and possibly this could cause issues if you are blocking the execute method, does the Arp::Mutex allow the watchdog timer not to be triggered?
If I use a std::thread which gets created in the constructor and that thread uses a std::mutex to restrict removing from a queue. There is another function which also uses the same std::mutex to restrict adding to the queue. Since they are never used in the Execute method, is it a poor assumption to make that it won't affect the execute method. Or is there a better way to write programs that are non-realtime to run on the plc?
Comments
Firstly, remember that the Automation Runtime Platform (Arp) abstracts all platform-specific implementations like threading, which may or may not be implemented using pthread (depending on the platform).
Here is the explanation from a developer:
The main technical reason to use Arp's Mutex class is priority inheritance. This is not enabled in
std::mutex
and can cause problems if at least one thread with real time priority wants to get the lock. In this case the priority of the thread holding the mutex is boosted to the priority of the thread waiting to get the mutex.Details:
One could use
std::mutex::native_handle()
to get a reference to the underlying thread implementation of astd::mutex
, hope (or check) that it is based on pthread, and then set the priority inheritance. But that is not portable. To use the same code on Windows and Linux we created our own abstractions.To answer your final question:
is there a better way to write programs that are non-realtime to run on the plc?
If I understand the question correctly, then yes. Non-real time applications should be written using ACF Components and (for example) a Worker Thread that periodically calls a function defined in the ACF Component. Data can be exchanged with other ACF Component instances, or with real-time Program instances, using GDS Port variables.
Thanks for your response Martin
Is there any Arp implementation of std::condition_variable?
After some discussion with the developers it turns out that there is an ARP implementation of std::condition_variable, but this has somehow not been included in the SDK. This has now been flagged and it will be included in future versions of the SDKs.
In the mean time, I'm told that it's possible to use an AutoResetEvent instead. From the developers:
That is a synchroniszation primitive adopted from .NET. Think of it as a combination of a flag guarded by a mutex and awaitable by a condition variable.
The AutoResetEvent is not a drop in replacement but may cover some use cases.
Is there any Arp implementation of std::condition_variable?
Just to close this off, the SDK for firmware version 2024.0.6 (and all future versions) will include the Arp implementation of std::condition_variable.