Threading to read COM ports with libmodbus - c

I am completely new to threading in C so wanted to check my idea was valid and relatively straightforward to program before starting on it. I want to write a program that can read from 2 COM ports simultaneously on two different threads (One thread per COM port) using Modbus RTU. I am relatively proficient using libmodbus functions etc it is just the threading part I require help with.
So, a few questions:
1) Is this possible to implement relatively easily (any examples no matter how simple would be much appreciated), and if so what considerations with regards to memory will need to be made?
2) Which relevant header files are required to implement multithreading in C?

So, a few questions: 1) Is this possible to implement relatively easily (any examples no matter how simple would be much appreciated)
Threading is a rather advanced topic in itself, and then you also have the system-specific ways of using a COM port. You'll have to study multi-threading and the OS-specific COM port library routines. It is not trivial.
what considerations with regards to memory will need to be made?
Shouldn't be a concern, except that you might want to implement some buffer system, which in turn must be protected by mutexes if used by multiple threads.
Which relevant header files are required to implement multithreading in C?
Depends on the system. For Linux and other POSIX systems, use pthreads (POSIX threads) from pthread.h. They may or may not be supported by a Windows compiler. Otherwise, Windows uses its own thread routines, CreateThread etc. RAD tools like Visual Studio or C++ Builder have wrapper classes around CreateThread. Other systems might have different libraries.
There was an attempt to standardize threading with the C11 standard, but that one is still in the experimental phase and we have yet to tell if it will be used or turn out a fiasco - few if any compilers support C11 threads. For now, pthreads is the most used industry standard.

Related

Is there any benefit to using a barrier over a semaphore?

Preface:
I'm maintaining some code in a library that currently uses a cross-platform implementation of semaphores to sync a few threads one time at the beginning of the program. The semaphore implementation is a thin wrapper around the pthread library in linux and around winbase's semaphore calls in Windows. This platform agnostic code only needs to operate on those two systems.
My conundrum:
I would like to switch to a barrier implementation, because that's all the semaphores are being used for in this library anyway. However, in order to add this functionality, I would have to add similar platform agnostic code for a barrier. Since Windows's barrier synchronization barrier API is quite different from it's other thread-related code (mutex and semaphores), it would be a fair bit of work to translate the Windows sync code into the platform agnostic version. I would like to make the change to barriers, but if there is no benefit to using barriers then I see no reason to go through the hassle of making a new implementation for a library that already works with semaphores.
Question:
Is there any performance benefit (or other benefit) that using a synchronization barrier would give over using a plain old semaphore implementation?

Why do we need a RTOS on ARM Cortex-M

If we can already execute C programs on cortex-m like micro-controllers, Why do we even need to install RTOS (or other operating systems).?
What benefits it can provide if micro-controller is intended to be multi-purpose.?
No you dont need an RTOS only if you need/want the features of the (particular) RTOS. You can program the microcontroller the way you/we always have without one if you prefer.
Typical things an RTOS might bring,
Memory management (who owns memory)
Interrupt handling support
Scheduling (pre-emptive or co-operative)
Usually several drivers in a BSP for your hardware/SOC
Debug tools
Some sort of shell
File systems
IPC (inter-process communitation)
A tool suite
A build environment
Memory protection
Networking
Your application may or may not need these features depending on your end goal. Some of them may be detrimental to your organizations work flow (like the tool suite and build environment). As a product matures, you may end up needing features you didn't account for.
However, a completely custom solution will probably have a smaller foot print. The race conditions involved in interrupt handling can be quite difficult to get right. Probably most RTOS will give a better implementation than something custom that evolves over time. If you are very dedicated, a state machine with polling of devices can be more optimal (hard real time) but again it is difficult to get right.
If the RTOS is BSD (or other permissive) licensed , it maybe possible to reuse the driver code to your own custom infra-structure. At some point your code may become an 'RTOS' of sorts. There are many to choose from.
POSIX compliance is a common standard. If you confine your code to POSIX, you are portable to many different RTOS/OS. However, most often an API that is more rich than POSIX; it is one way they differentiate each other. You may be able to use more 3rd party libraries if the RTOS is POSIX compliant.
An operating system provides a level of abstraction between the code written by an application programmer and the actual hardware the program runs on.
So you don't have to worry, as an application programmer, about the details of the hardware, as they are handled by drivers.
And thus you can compile the same program for many different hardware platforms, if they run the same (or a compatible) operating system.

How to portably share a variable between threads/processes?

I have a server that spawns a new process or thread for every incoming request and I need to read and write a variable defined in this server from both threads and processes. Since the server program needs to work both on UNIX and Windows I need to share the variable in a portable way, but how do I do it?
I need to use the standard C library or the native syscalls, so please don’t suggest third party libraries.
shared memory is operating system specific. On Linux, consider reading shm_overview(7) and (since with shared memory you always need some way to synchronize) sem_overview(7).
Of course you need to find out the similar (but probably not equivalent) Windows function calls.
Notice that threads are not the same as processes. Threads by definition share a common single address space. With threads, the main issue is then mostly synchronization, often using mutexes (e.g. pthread_mutex_lock etc...). On Linux, read a pthread tutorial & pthreads(7)
Recall that several libraries (glib, QtCore, Poco, ...) provide useful abstractions above operating system specific functionalities, but you seem to want avoiding them.
At last, I am not at all sure that sharing a variable like you ask is the best way to achieve your goals (I would definitely consider some message passing approach with an event loop: pipe(7) & poll(2), perhaps with a textual protocol à la JSON).

Is C select() function deprecated?

I am reading a book about network progamming in C. It is from 2004.
In the example code, author is using select C function to accept multiple connections from the client. Is that function deprecated today?
I see that there are different ways to accept multiplexed I/O like poll and epoll. What are the advantages?
It's not deprecated, and lots of programs rely on it.
It's just not the best tool as it has some limitations:
The number of file descriptors is limited (OS specific, usually possible to increase it with kernel recompiling).
Doesn't scale well (with lots of fds): the whole FD set must be maintained, and re-initialized as select manipulates it.
Feel free to use it if these aren't relevant for you. Otherwise use poll/libevent if you're looking for a cross-platform solution, or in some rare-cases epoll/kqueue for platform specific optimized solutions.
It's not deprecated in its behavior, but its design may have performance issues. For example, linux epoll() documentation states:
API can be used either as an edge-triggered or a level-triggered inter‐
face and scales well to large numbers of watched file descriptors.
Since the efficient alternatives are specific to each operating system, an option better than directly using select() is to use a cross platform multiplexing library (which uses the best implementation available), examples being:
libevent
libev
libuv
If you're developing for a specific operating system, use the recommended implementation for high performance applications.
However, since some people don't like current libraries for I/O multiplexing (due to "being ugly"), select is still a viable alternative.

Threading in C, cross platform

I am dealing with an existing project (in C) that is currently running on a single thread, and we would like to run on multiple platforms AND have multiple threads. Hopefully, there is a library for this, because, IMHO, the Win32 API is like poking yourself in the eye repeatedly. I know about Boost.Thread for C++, but, this must be C (and compilable on MinGW and gcc). Cygwin is not an option, sorry.
Try OpenMP API, it's multi-platform and you can compile it with GCC.
Brief description from the wikipedia:
OpenMP (Open Multi-Processing) is an application programming interface
(API) that supports multi-platform shared memory multiprocessing
programming in C, C++, and Fortran,[3] on most platforms, processor
architectures and operating systems, including Solaris, AIX, HP-UX,
Linux, macOS, and Windows. It consists of a set of compiler
directives, library routines, and environment variables that influence
run-time behavior.
I would use the POSIX thread API - pthread. This article has some hints for implementing it on Windows, and a header-file-only download (BSD license):
http://locklessinc.com/articles/pthreads_on_windows/
Edit: I used the sourceforge pthreads-win32 project in the past for multi-platform threading and it worked really nicely. Things have moved on since then and the above link seems more up-to-date, though I haven't tried it. This answer assumes of course that pthreads are available on your non-Windows targets (for Mac / Linux I should think they are, probably even embedded)
Windows threading has sufficiently different functionality when compared to that of Linux such that perhaps you should consider two different implementations, at least if application performance could be an issue. On the other hand, simply implementing multi-threading may well make your app slower than it was before. Lets assume that performance is an issue and that multi-threading is the best option.
With Windows threads I'm specifically thinking of I/O Completion Ports (IOCPs) which allow implementing I/O-event driven threads that make the most efficient use of the hardware.
Many "classic" applications are constructed along one thread/one socket (/one user or similar) concept where the number of simultaneous sessions will be limited by the scheduler's ability to handle large numbers of threads (>1000). The IOCP concept allows limiting the number of threads to the number of cores in your system which means that the scheduler will have very little to do. The threads will only execute when the IOCP releases them after an I/O event has occurred. The thread services the IOC, (typically) initiates a new I/O and returns to wait at the IOCP for the next completion. Before releasing a thread the IOCP will also provide the context of the completion such that the thread will "know" what processing context the IOC belongs to.
The IOCP concept completely does away with polling which is a great resource waster although "wait on multiple object" polling is somewhat of an improvement. The last time I looked Linux had nothing remotely like IOCPs so a Linux multi-threaded application would be constructed quite differently compared to a Windows app with IOCPs.
In really efficient IOCP apps there is a risk that so many IOs (or rather Outputs) are queued to the IO resource involved that the system runs out of non-paged memory to store them. Conversely, in really inefficient IOCP apps there is a risk that so many Inputs are queued (waiting to be serviced) that the non-paged memory is exhausted when trying to temporarily buffer them.
If someone needs a portable and lightweight solution for threading in C, take a look at the plibsys library. It provides you thread management and synchronization, as well as other useful features like portable socket implementation. All major operating systems (Windows, Linux, OS X) are supported, various other less popular operating systems are also supported (i.e. AIX, HP-UX, Solaris, QNX, IRIX, etc). On every platform only the native calls are used to minimize the overheads. The library is fully covered with Unit tests which are run on a regular basis.
glib threads can be compiled cross-platforms.
The "best"/"simplest"/... answer here is definitely pthreads. It's the native threading architecture on Unix/POSIX systems and works almost as good on Windows. No need to look any further.
Given that you are constrained with C. I have two suggestions:
1) I have a seen a project (similar to yours) that had to run on Windows and Linux with threads. The way it was written was that it (the same codebase) used pthreads on Linux and win32 threads on Windows. This was achieved by a conditional #ifdef statement wherever threads needed to be created such as
#ifdef WIN32
//use win32 threads
#else
//use pthreads
#endif
2) The second suggestion might be to use OpenMP. Have you considered OpenMP at all?
Please let me know if I missed something or if you want more details. I am happy to help.
Best,
Krishna
From my experience, multi threading in C for windows is heavily tied to Win32 APIs. Other languages like C# and JAVA supported by a framework also tie into these core libraries while offering their thread classes.
However, I did find an openthreads API platform on sourceforge which might help you:
http://openthreads.sourceforge.net/
The API is modeled with respect to the Java and POSIX thread standard,
I have not tried this myself as I currently do not have a need to support multiple platforms on my C/C++ projects.

Resources