SilentCat
SilentCat

Reputation: 75

Shared memory synchronisation between three processes in linux

In a Linux based system I am having 3 processes (A,B,C) having a shared memory to be accessed in all. The Process A continuously updates the shared memory values with the real time value updated inside the Process. The Process B reads the shared memory and output the values in Terminal (upon user request). The Process C is a server program which waits for a connection and upon a successful connection the shared memory values are read and then the values are send to the client. I am trying to establish a synchronisation between the 3 process with any techniques. When I thought of implementing it with Semaphores, the main concern is with the Process A. Process A is a never ending monitoring process and it is not to be kept in wait state at any instant of time, since its of high priority. The Process B and C has to obtain the updated shared memory values upon user request. How can I achieve this ? Sample code is given below.

Process A

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    while(1)
    {
       //*************************************/
       //Monitoring routines******************/
       //*************************************/
       UpdateValuesToSharedMemory();  //function to update monitored values to shared memory
    }
}

Process B

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    while(1)
    {
    do
    {
        scInString[ucLocal1]  = getchar();
        ucLocal1++;
        if(scInString[ucLocal1-1] == '\n')
        {
        break;
        }
    }while(ucLocal1<6);
    UpdateValuesFromSharedMemory();  //function to update monitored values to shared memory
    DisplayValues();  // Function to display the obtained values for shared memory      
    }
 }

Process C

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    void *context = zmq_ctx_new ();
    responder = zmq_socket (context, ZMQ_REP);
    int rc = zmq_bind (responder, "tcp://*:5555");
    assert (rc == 0);
    while (1) {

        memset(buffer,'/0',2500);
        zmq_recv (responder, buffer, 2500, 0);      //Collect the request from the client
        UpdateValuesFromSharedMemory();  //function to update monitored values to shared memory

        json_object * jobjRcvd = json_tokener_parse(buffer);
        id = iGetCommandID(jobjRcvd);               //Find the command id

        cFunctionCommands[(id-1)](jobjRcvd);        //Call the function to prepare the reply with respect to the command
        zmq_send (responder, (char * )jsonmsg,strlen(jsonmsg), 0);//Reply to the client
       }
     }

Upvotes: 1

Views: 6371

Answers (1)

Reinier Torenbeek
Reinier Torenbeek

Reputation: 17363

There are many different kinds of Mutual exclusion objects available for this.

For your use-case, the simplest approach would be to use a standard pthread mutex. Before updating or reading the data block, each process has to invoke pthread_mutex_lock() followed by the update or read action, followed by pthread_mutex_unlock().

See the man page for pthread_mutex_init() for instructions on how to create a mutex like that. In particular, since you want to do synchronization between processes, you will need to initialize the mutex as PTHREAD_PROCESS_SHARED. This is explained in detail, with an example, in the man page for pthread_mutexattr_init(), in the section called Process Shared Memory and Synchronization.

The mutex object itself needs to be accessible to all processes. Since you already have a shared memory segment available, you could choose to reuse that for storing your mutex object. In that case, all processes need to know where to look in that block. You could achieve this by embedding the mutex structure in what you call some struct in your code example. The code example in the man page opens a separate file for that purpose.

Theoretically, a pthread_rwlock_t type would fit the bill better (pointed out by user oakad)(ignoring any potential CPU penalties and other implementation details), but I chose to point you to the mutex because it has more example code in the man page.

Upvotes: 2

Related Questions