How to control two processes with posix and semahrores in C++?

Hi

Im new to Concurrency and parallelism programming in C/C++ so I need some help with my project.

I want to run multiple process using POSIX and Semaphores in C++. So the structure of the program should be the following one. First I Open Serial port (Serial communication of the Raspberry PI 4). While the Serial is Open Two processes are running

First one, the main one run automatically and do the following: The thread ask for ODOM Updates(Pressure and IMU from the microcontroller) and Publish them. Also every 0.3 seconds check the modem inbox and if something new it publish.

The other one only on DEMAND from ROS Services detect that there is new message in the modem inbox do HALT( on the first main Process) and execute (publish) on the serial Port. Then the first process resume with normal work

So first I trying to do first some pseudo C++ code that looks like these But I need help as Im new to Concurrency and parallelism. Here it is



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#include <unistd.h>
#include <wiringSerial.h>

sem_t mutex;

void* thread(void* arg) { //function which act like thread

   //Main Thread
   // Here code for ASK ODOM UPDATE..
   // Here code for CHECK MODEM INBOX...
   sem_wait(&mutex); //wait state
   
   // ENTER in the second Process
   // Here code for the second process which run on DEMAND..
   // ROS SERVICES
   
   // Here code for CHECK The MODEM INBOX and HALT the First Process
   // Here code for EXECUTE on SERIAL PORT(PUBLISH)
   sleep(0.1); //critical section 
   printf("\nCompleted...\n"); //comming out from Critical section
   sem_post(&mutex);
}

main() {
   
   int serial_port = serialOpen ("/dev/serial0",115200);
   if (serial_port > 0) {
   
   
   sem_init(&mutex, 0, 1);
   pthread_t th1,th2;
   pthread_create(&th1,NULL,thread,NULL);
   sleep(1);
   pthread_create(&th2,NULL,thread,NULL);
   //Join threads with the main thread
   pthread_join(th1,NULL);
   pthread_join(th2,NULL);
   sem_destroy(&mutex);
 }

}


So Im not sure this is the correct way of implementation on C++ . Any help in the implementation and maybe help on the actual C++ code? Thanks
Last edited on
I'd suggest using the standard library features.
https://en.cppreference.com/w/cpp/thread

These have been part of the standard for a decade now, so you should be able to use them.
So I have to use threads and semaphores right? Please can have bit help in the pseudo code as Im beginner in threads and never use them? Or Futures such as

The standard library provides facilities to obtain values that are returned and to catch exceptions that are thrown by asynchronous tasks (i.e. functions launched in separate threads).
Last edited on
cppreference has example usage of pretty much everything you need to know.
https://en.cppreference.com/w/cpp/thread/mutex

Why do you think that you need threads?

detect that there is new message in the modem inbox do HALT( on the first main Process) and execute (publish) on the serial Port.
Can't you do this within your normal main processing? Since both checking the inbox just doing something different depending on the content.
I need threads and semaphores because the first main process should run automatically (ask for odom update and chec Modem inbox). But the second process run only when execute a command in the Raspberry Pi ( and call ROS Services) so can HALT the first process . Thats what Concurrency and parallelism programming in C/C+ is about , right? Or Do I miss something?
Last edited on
But you're only reading from a single device (the modem), one character at a time, over the serial line.

So you have a single loop that reads enough characters to decide what to do.

It looks like your two "activities" would be best modelled as a FSM, not as threads.
https://en.wikipedia.org/wiki/Finite-state_machine

It might be even simpler than that; it's just a ping-pong.
If you're not doing one, you're doing the other, and just bouncing between them alternately.
No no I think you understand it wrong. I didnt mentioned that the both process running while the serial port is open (so the serial communication is always open while the operation). The First process must run automatically Its not ping pong. As the application is underwater Remote Operated Vehicle (ROV) so the communication must be continuous . Its not a pink Pong. So the first process must running in main automatically. And the second only on DEMAND.
Thats what Concurrency and parallelism programming in C/C+ is about , right?
No. I think you overrate that 'on demand' part. It may be just a simple bool.

Threads are not used for halt but the opposite reason: prevent blocking.

For instance when 'asking for ODOM Updates' would takes too long, so that the '0.3 seconds check' cannot be fulfilled then you should consider to put the update/check process in separate threads. That's just an example another bottleneck could be the 'publish'ing.

From what you described the 'ROS Services' process and the '0.3 seconds check' process are doing the same: publish.
So what's the different that may require a thread and what's so important about the 'halt'?
So who's reading the serial line?
Can I attach Image? I have Image of the Firmware and Middleware of the Robot. So my the robot have a Raspberry Pi with (ROS and Python-Driver) controlled by Middleware. Than I have ESP32 Microcotroller (with Motors, Sensors) controlled by Low Level Software . So the only way that Raspberry PI communicate with the ESP32 is through the serial port. So that why the serial port must be open all the time during the operation of the robot.
On the raspberry pi I have Camera , ROS and Python-Driver. On the ESP32 I have the Robot Motors, Sensors, and Modem
https://imgur.com/ is a reasonable enough place to attach images.

> Its not a pink Pong. So the first process must running in main automatically. And the second only on DEMAND.
It's still ping-pong if you're only doing one of two things.

You don't halt the first thing, you simply call the 2nd thing "on demand".
So the only way that Raspberry PI communicate with the ESP32 is through the serial port.
Note that it is not possible that two threads access a single serial port.
here the image of my hardware and software https://imgur.com/a/COAgPe9
The raspberry pi 4 has 4 cores. So you can have 4 thread for 'free'. My suggestion would be:

One Thread for the communication with

1. the User Computer
2. the driver/microcontroller
3. the camera

and the main thread for coordinating and direct input. I looks like this constellation kind of requires this.
For the threading I suggest using std::thread:

http://www.cplusplus.com/reference/thread/thread/

Before you start threading I suggest that you create a test project for each device and develop the communication individually.

By the way: What does ROS stand for? And how is it involved? This might have an impact on your architecture. I.e. this?

https://discourse.ros.org/t/ros-2-galactic-geochelone-released/20559
ROS (Robot Operating System) is the ROBOT midlware. is the high level software, such as controller, all the sensors messages, At the moment we are using ROS1 and Noetic in Ubuntu 20
Last edited on
Take a look at this:

http://wiki.ros.org/roscpp_tutorials/Tutorials/WritingPublisherSubscriber

At '2.1 The Code' line 75: where the subscriber is added. Ideally you can add a 'subscriber' for each device which are 'User Computer etc.'. Then you don't need different threads for the different devices.

The question would be: Can the system/ros be configured so that you can actually subscribe to 3 different devices...
Topic archived. No new replies allowed.