Tag Archives: ipc

Shared Memory IPC Ping-pong Sequence

Overview

In this post, I am sharing an example of IPC communication with a class using shared memory.

Two processes runs together, and their applications sequentially running. The end of each loop is marked at a shared memory with a “go-flag”. Once the other process see the end-of-the-loop flag, “go-flag”, the process continues the task.

Shared Memory IPC Class

I wrote this class to make the shared memory programming more portable. What you need to do is only to change the struct called “shared_memory_packet. You will see how to use this class in the examples of the next section. You can see the code of “shared_memory_base.h” and “shared_memory_base.cpp” below:

#ifndef SHARED_MEMORY_BASE_H
#define SHARED_MEMORY_BASE_H

#include <sys/ipc.h>
#include <sys/shm.h>

#define DEFAULT_KEY_ID  5700        // default key for shared memory

class shared_memory_base
{
    struct shared_memory_packet {
        float analog_input[16];
        bool go_flag_second_loop = 1;
        bool go_flag_first_loop = 1;
    };

private:
    key_t key;
    int shmid = 0;
public:
    shared_memory_base();
    ~shared_memory_base();

    shared_memory_packet* data;
    void init();
    void change_shared_memory_key(key_t k){key= k;} // only use this function before init
    void detach_shared_memory();
};

#endif // SHARED_MEMORY_BASE_H
#include "shared_memory_base.h"

shared_memory_base::shared_memory_base()
{
    key = ftok("shmfile",DEFAULT_KEY_ID);
}

shared_memory_base::~shared_memory_base(){
    detach_shared_memory();
}

void shared_memory_base::init(){
    // shmget returns an identifier in shmid
    shared_memory_packet temp;
    shmid = shmget(key, sizeof(temp),0666|IPC_CREAT);
    // shmat to attach to shared memory
    data = (shared_memory_packet*) shmat(shmid,(void*)0,0);
}

void shared_memory_base::detach_shared_memory(){
    shmdt(data);
    shmctl(shmid,IPC_RMID,nullptr);
}

Ping-pong Sequence between Two Processes

In this example, “first_app.cpp” the number of an integer variable incrementally, and change the “go_flag_second_loop” to be one. In “second_app.cpp” the number of an integer variable is reduced, and change the “go_flag_first_loop” to be one. With this two go_flags two processes run sequencially.

#include <iostream>
#include <unistd.h>
#include "shared_memory_base.h"

using namespace std;

int main()
{
    shared_memory_base comm;
    comm.init();

    comm.data->analog_input[0] =0;
    comm.data->analog_input[8] =0;

    for (int i=0;i<10;i++){
        while( comm.data->go_flag_first_loop != 1);
        comm.data->analog_input[0] = i;
        cout << "ai[8]: " << comm.data->analog_input[8] << endl;
        comm.data->go_flag_second_loop = 1;
        sleep(1);
    }

    cout << "end of the loop!" << endl;
    comm.detach_shared_memory();
    return 0;
}
#include <iostream>
#include "shared_memory_base.h"

using namespace std;

int main()
{
    shared_memory_base comm;
    comm.init();

    comm.data->analog_input[0] =0;
    comm.data->analog_input[8] =0;
    comm.data->go_flag_first_loop = 1;

    for (int i=0;i<10;i++){
        while( comm.data->go_flag_second_loop != 1);
        comm.data->analog_input[8] = 1000-i;
        cout << "ai[0]: " << comm.data->analog_input[0] << endl;
        comm.data->go_flag_second_loop = 0;
    }

    cout << "end of the loop!" << endl;
    comm.detach_shared_memory();
    return 0;
}

Result

The figures below shows the execution results of two applications.

Execution Result of “First_app”
Execution Result of “Second_app”

Download and Build the Codes

You can download the entire code and can build the code with the command below:

Download link

mkdir build
cd build
cmake ../shared_memory_example
make

More discussion

Concurrency problem is a very well-known and challenging problem. There are many other nice techniques other than this one. Particularly after C++11, the standard C++ has introduced a nice set of concurrent thread and process running functions. In addition, this example is not the best code for efficient applications.

I found a very good reference explaining Concurrency, Parallelism, Threads, Processes, Async and Sync. For the details, read the article in the link below:

https://medium.com/swift-india/concurrency-parallelism-threads-processes-async-and-sync-related-39fd951bc61d