Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Write your own simple client/server set of processes in the C language. There should be two files: client.c and server.c. The client should use a

Write your own simple client/server set of processes in the C language. There should be two files: client.c and server.c.

The client should use a shared memory segment to send a command message to the server.

You may not use sockets or multithreading, as we have not gone over that yet in my class. We are supposed to be using semaphores and shared memory segments.

The server process should monitor the shared memory segment, and respond as follows: "HI" -- The server prints "Greetings" to the screen. "PID" -- The server prints it's process id to the screen. "QUIT" -- The server terminates gracefully, detaching and releasing the shared memory segment.

**Note, please do not copy and paste a solution from here or Google. I am looking for a unique solution to help me better understand this assignment. Thank you.**

Hints :

Use polling (an intentional infinite loop) in the server to monitor the shared memory segment.

You will need some way to coordinate sharing the memory segment.

read man pages for shmdt, shmget, shmat, shmctl, semctl, semop, semget

image text in transcribed

I will now attach the code that I have so far, I am getting an error with the client.c saying "semget: File exists". I have tried changing the keys for semget but that doesn't seem to work. I don't know why it is saying I already have semaphores for those keys. The server runs fine, so far. Not sure if its done though.

Here is my server code so far:

#include "stdio.h" #include "stdlib.h" #include "sys/shm.h" #include "sys/ipc.h" #include "time.h" #include "sys/types.h" #include "sys/sem.h" #include "signal.h" #include "string.h" #include

#define MEM_KEY 90 // like a filename #define SEM_KEY 9900 #define SEG_SIZE ( (size_t)100 ) // size of segment #define oops( m, x ) { perror(m); exit(x); } int seg_id, semset_id; union semun{ int val; struct semid_ds* buf; ushort* array; }; void wait_and_lock( int ); void release_lock( int );

int main() { char c; char *memPtr;

if ((seg_id = shmget(MEM_KEY, SEG_SIZE, IPC_CREAT | 0777))

if ((memPtr = shmat(seg_id, NULL, 0)) == (char *) -1) oops("shmat", 2); semset_id = semget( SEM_KEY, 2, 0666 );

wait_and_lock( semset_id );

while(1) { printf("enter: "); scanf("%s", memPtr); }

release_lock( semset_id ); while (*memPtr != '*') sleep(1); shmdt( memPtr );

exit(0); }

void wait_and_lock( int semset_id ) { union semun sem_info; // some properties struct sembuf actions[2]; // action set, an array actions[0].sem_num = 1; // sem[1] is n_writers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = 0; // wait for 0 actions[1].sem_num = 0; // sem[0] is n_readers actions[1].sem_flg = SEM_UNDO; // auto cleanup actions[1].sem_op = 1; // incr n_readers if ( semop( semset_id, actions, 2 ) == -1 ) oops( "semop: locking", 10 ); }

void release_lock( int semset_id ) { union semun sem_info; // some properties struct sembuf actions[1]; // action set actions[0].sem_num = 0; // sem[0] is n_readers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = -1; // decr reader country if ( semop( semset_id, actions, 1 ) == -1 ) oops( "semop: unlocking", 10 ); }

and here is my client code so far:

#include "stdio.h" #include "stdlib.h" #include "sys/shm.h" #include "sys/ipc.h" #include "time.h" #include "sys/types.h" #include "sys/sem.h" #include "signal.h" #include "string.h" #include

#define MEM_KEY 90 // like a filename #define SEM_KEY 9900 #define SEG_SIZE ( (size_t)100 ) // size of segment #define oops( m, x ) { perror(m); exit(x); }

union semun { int val; struct semid_ds* buf; unsigned short* array; }; int seg_id, semset_id; void cleanup( int ); void set_sem_value( int, int, int ); void wait_and_lock( int ); void release_lock( int );

int main() { int id = 0; char *memPtr, *s; signal( SIGINT, cleanup ); seg_id = shmget( MEM_KEY, SEG_SIZE, 0777 ); if( seg_id == -1 ) oops( "shmget", 1 );

if ((memPtr = shmat(seg_id, NULL, 0)) == (char *) -1) oops("shmat",2); semset_id = semget( SEM_KEY, 2, ( 0666 | IPC_CREAT | IPC_EXCL ) ); if ( semset_id == -1 ) oops( "semget", 3 ); set_sem_value( semset_id, 0, 0 ); set_sem_value( semset_id, 1, 0 );

//Now read what the server put in the memory. //while(1){ //for (s = shm; *s != '\0'; s++) //putchar(*s); //} while(1) { wait_and_lock( semset_id ); printf( "\tshm_ts2 update memory " ); if(strcmp(memPtr, "HI")==0) { printf("Greetings! "); fflush(stdout); memPtr[0] = '\0';

} else if(strcmp(memPtr, "PID")==0) { id = (int)getpid(); printf("Server pid: %i ", id); fflush(stdout); memPtr[0] = '\0'; } else if(strcmp(memPtr, "QUIT")==0){ shmctl(seg_id, IPC_RMID, NULL); shmdt(memPtr); printf("GOODBYE! "); exit(0); } release_lock( semset_id ); printf( "\tshm_ts2 released lock " ); }

//putchar(' '); *memPtr = '*'; cleanup(0); return 0;

}

void cleanup( int n ) { shmctl( seg_id, IPC_RMID, NULL ); semctl( semset_id, 0, IPC_RMID, NULL ); }

void set_sem_value( int semset_id, int semnum, int val ) { union semun initval; initval.val = val; if ( semctl( semset_id, semnum, SETVAL, initval ) == -1 ) oops( "semctl", 4 ); }

void wait_and_lock( int semset_id ) { struct sembuf actions[2]; // action set, an array actions[0].sem_num = 0; // sem[0] is n_readers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = 0; // wait til no readers actions[1].sem_num = 1; // sem[1] is n_writers actions[1].sem_flg = SEM_UNDO; // auto cleanup actions[1].sem_op = 1; // increment number of writers if ( semop( semset_id, actions, 2 ) == -1 ) oops("semop: locking", 10 ); }

// Thing 4: build and execute a 1-element action set: decrement num_writers void release_lock( int semset_id ) { struct sembuf actions[1]; // action set, an array actions[0].sem_num = 1; // sem[0] is n_writers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = -1; // decrement number of writer count if ( semop( semset_id, actions, 1 ) == -1 ) oops( "semop: unlocking", 10 ); }

A 10-point sample run: Terminal 1: rig N$ cc cl.c ocl cat rig N HI PID QUIT trig N]$ Terminal 2 at rig ne]$ cc server.c Server crig ne]$ ./server Greetings! Server pid: 24700 GOODBYE

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Murach's SQL Server 2012 For Developers

Authors: Bryan Syverson, Joel Murach, Mike Murach

1st Edition

1890774693, 9781890774691

More Books

Students also viewed these Databases questions

Question

600 lb 20 0.5 ft 30 30 5 ft

Answered: 1 week ago