Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Help needed One of the limitations of a shared memory is lack of synchronization

ID: 3776475 • Letter: H

Question

Help needed

One of the limitations of a shared memory is lack of synchronization where it is the responsibility of the programmer to use tools that guarantee synchronization between processes:

A producer process should wait for the consumer process to read the buffer before the producer writes again (so it does not overwrite data that is not read yet).

A consumer process should wait for the producer process before it reads the buffer again and process the data (so it does not process old data)

One simple way to achieve synchronization is using a flag where each process does its work and updates a flag. A consumer process will not read again until the new_data_flag is set (i.e. set to 1). A producer process will not write again until the new_data_flag is reset (i.e. set to 0).

Use the previous code as the base to create 2 programs that use shared memory to communicate:

A Sender.c program: will read a message (one word) from the user and writes it to the shared memory then exits.

A Receiver.c program: will continuously monitor the shared memory and every time a new message is written, it prints it to the screen and wait for the next one.

Use the following shared memory structure:

#define MAX_SIZE 128 struct info {

int new_data_flag; //either 0 or 1 char text[MAX_SIZE];

};

The new_data_flag part of the info shared memory structure is changed (i.e. set to 1) by the sender process after it writes to the text part of info.

The receiver process will reset the new_data_flag part of the shared memory (i.e. set to 0), and go into an infinite loop waiting for the flag to change. When the new_data_flag changes its value (e.g. set to 1 by the sender process to indicate new data), the process stops waiting, prints the message and changes the flag back to initial value (e.g. set to 0) which causes the receiver to wait until something new is written by the sender.

The receiver keeps reading and printing messages sent by the sender process until it receives a message ‘quit’.

Use the following two funcs in the code:

int shmget(key_t key, size_t size, int shmflg);

void *shmat(int shmid, const void *shmaddr, int shmflg);

Explanation / Answer

//sender.c

#include <stdio.h>
#include<sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#define MAX_SIZE 128
struct info
{
int new_data_flag; //either 0 or 1
char text[MAX_SIZE];
};

struct info *sender;

int main()
{
int shmid;
int key=5678;
int flag = 0666;
char text[MAX_SIZE];
  
//shmid = shmget(key,sizeof(struct info),flag);
shmid = shmget(key, sizeof(struct info), IPC_CREAT | 0666);
  
if( shmid < 0 )
{
perror("shmget");
return -1;
}
  
printf("Read msg from sender: ");
//sender =(struct info*)malloc(128);
//scanf("%s",text);
fgets(text,MAX_SIZE,stdin);
printf("Msg read from sender process = %s ",text);
  
flag = 1;
  
sender=(struct info*)shmat(shmid,0,0);
printf("shared memory addr at sender= %u ",sender);
memcpy((char*)sender->text,(char*)text,MAX_SIZE);
sender->new_data_flag = flag;

  
  
}

----------------------------------------------------------------------------------------------------

//recv.c

//recv.c
#include <stdio.h>
#include<sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#define MAX_SIZE 128
struct info
{
int new_data_flag; //either 0 or 1
char text[MAX_SIZE];
};

struct info *recv;

int main()
{
int shmid;
int key=5678;
int flag = 0666;
  
shmid = shmget(key,sizeof(struct info),flag);
  
if( shmid < 0 )
{
perror("shmget");
return -1;
}
printf("Waiting from message from sender ");
recv = shmat(shmid,0,0);
printf("Address of shared memory at recv= %u ",recv);
while(1)
{
if(recv->new_data_flag == 1 )
{
printf("Received msg from sender = %s ",recv->text );
recv->new_data_flag = 0;
}
  
  
}
  
}