user3397765
user3397765

Reputation: 41

POSIX in C semaphore with fork and shared memory,

I am trying to do a program with semaphore and fork and shared memory

the parent suppose to create the shared memory and insert numbers to the buffer print done then the child going to read from shared memory and print the sum of the numbers the program run but only the parent print done but the child does not do any thing,

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <stdio.h>

#include <netinet/in.h>
#include <netdb.h> 

#include<netinet/in.h>
#include<netdb.h>
#include<sys/wait.h>
#include<unistd.h>

#include <sys/shm.h>




char buffer[10];
char *data; 
    int commNo =0;
    key_t key;
    int shmid;
    char *shrmem;
    int mode;

void error(char *msg)
{
    perror(msg);
    exit(0);
}
int rem[10];

key_t key; /* key to pass to semget() */ 
key_t key1; /* key to pass to semget() */ 
key_t key2; /* key to pass to semget() */ 
key_t key3; /* key to pass to semget() */ 
int semflg; /* semflg to pass tosemget() */ 
int nsems; /* nsems to pass to semget() */ 
int semid; /* return value from semget() */ 
#define   MAX_COUNT  200
#define  N  100      /* shared buffer of size 100 */

void  ChildProcess(void);                /* child process prototype  */
void  ParentProcess(void);               /* parent process prototype */




//things for ftok 
char *path = "/tmp";
int id = 'S';
//create sembuf

  //struct sembuf{
    //            ushort  sem_num;        /* semaphore index in array */
      //          short   sem_op;         /* semaphore operation */
        //        short   sem_flg;        /* operation flags */
        //};



int locksem = 1;     /* binary semaphore for  locking-unlocking: initiall  unlocked : 1 */
int emptysem = 100;  /* counting semaphore for  empty slots */
int fullsem = 0;      /* counting semaphore for  filled slots*/


 struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;

struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));

//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;



void creatmemory(){



      /* make the key: */
    if ((key = ftok("/tmp",1)) == -1) {

        perror("ftok");
        //clientnumber
        exit(1);
    }
      /* connect to (and possibly create) the segment: */
    if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1) {

        perror("shmget");
        exit(1);
    }


     /* attach to the segment to get a pointer to it: */

    data = shmat(shmid, (void *)0, 0);

    if (data == (char *)(-1)) {

        perror("shmat");
        exit(1);
    }


}




int main(int argc, char *argv[]){
     pid_t pid;

     nsems = 1;


//static struct sembuf oplock;
oplock.sem_num = 0;
oplock.sem_op = -1;
oplock.sem_flg = SEM_UNDO;


//static struct sembuf opunlock;
opunlock.sem_num = 0;
opunlock.sem_op = 1;
opunlock.sem_flg = SEM_UNDO;


//to create new one
semflg = IPC_CREAT;


         /* Get unique key for semaphore. */
if ((key1 =  ftok(path,1)) == (key_t) -1) {
    perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key2 =  ftok(path,2)) == (key_t) -1) {
    perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key3 =  ftok(path,3)) == (key_t) -1) {
    perror("IPC error: ftok"); exit(1);
}


     pid = fork();
     if (pid == 0) {

     //***************************************************************************************************************



//
int n =0;
while(n < 3){

locksem = semget(key1, nsems, semflg);   /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
    semop(fullsem,&oplock,1);  /* check filled slots */
    semop(locksem,&oplock,1);      /* lock shared buffer*/
   // itx= remove_item(); 
   /* remove an item from buffer */
   int i;
   for (i =0; i<10; i++){
   rem[i] = data[i];}
   bzero(buffer,10);
   bzero(data,strlen(data));
    /* detach from the segment: */
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }
    semop(locksem,&opunlock,1);  /* unlock the buffer */
    semop(emptysem,&opunlock,1);  /* increment emptysem*/
    //consume_item(itx);
    int sum = 0;
for(i =0; i<10; i++){
sum += rem[i];}
printf("the sum is:%d \n", sum);
    n++;} 
    }

         //consumer();
     else 
     {

      creatmemory();
     int n =0;
while( n < 3) {  

locksem = semget(key1, nsems, semflg);   /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);

bzero(buffer,10);
int i;
for(i =0; i<10; i++)
buffer[i] = i;

    semop(emptysem,&oplock,1);  /* check empty slots */
    semop(locksem,&oplock,1);      /* lock shared buffer*/
/* insert item into the buffer */

strncpy(data, buffer, strlen(buffer));  
printf("done \n");
    semop(locksem,&opunlock,1);  /* unlock the buffer */
    semop(fullsem,&opunlock,1);  /* increment fullsem*/

    sleep(10);      

     n++;}  
     }
         // producer();


}

Upvotes: 0

Views: 830

Answers (1)

user3629249
user3629249

Reputation: 16540

Here is a version of the code that actually compiles and links cleanly:

#define  _XOPEN_SOURCE (1) // needed by sys/ipc.h
#include <sys/types.h>

#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

#include <stdlib.h> // exit()
#include <string.h>
#include <strings.h> // bzero())

#include <netinet/in.h>
#include <netdb.h>

#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <unistd.h>

#include <sys/shm.h>




char buffer[10];
char *data;
int commNo =0;
key_t key;
int shmid;
char *shrmem;
int mode;

void error(char *);


int rem[10];

key_t key; /* key to pass to semget() */
key_t key1; /* key to pass to semget() */
key_t key2; /* key to pass to semget() */
key_t key3; /* key to pass to semget() */
int semflg; /* semflg to pass tosemget() */
int nsems; /* nsems to pass to semget() */
int semid; /* return value from semget() */
#define   MAX_COUNT  200
#define  N  100      /* shared buffer of size 100 */

void creatmemory( void );




//things for ftok
char *path = "/tmp";
int id = 'S';
//create sembuf

  //struct sembuf{
    //            ushort  sem_num;        /* semaphore index in array */
      //          short   sem_op;         /* semaphore operation */
        //        short   sem_flg;        /* operation flags */
        //};



int locksem = 1;     /* binary semaphore for  locking-unlocking: initiall  unlocked : 1 */
int emptysem = 100;  /* counting semaphore for  empty slots */
int fullsem = 0;      /* counting semaphore for  filled slots*/


 struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;

struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));

//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;








int main()
{
     pid_t pid;

     nsems = 1;


    //static struct sembuf oplock;
    oplock.sem_num = 0;
    oplock.sem_op = -1;
    oplock.sem_flg = SEM_UNDO;


    //static struct sembuf opunlock;
    opunlock.sem_num = 0;
    opunlock.sem_op = 1;
    opunlock.sem_flg = SEM_UNDO;


    //to create new one
    semflg = IPC_CREAT;


    /* Get unique key for semaphore. */
    if ((key1 =  ftok(path,1)) == (key_t) -1) {
        perror("IPC error: ftok"); exit(1);
    }

    /* Get unique key for semaphore. */
    if ((key2 =  ftok(path,2)) == (key_t) -1) {
        perror("IPC error: ftok"); exit(1);
    }

    /* Get unique key for semaphore. */
    if ((key3 =  ftok(path,3)) == (key_t) -1) {
        perror("IPC error: ftok"); exit(1);
    }


    if( 0 == (pid = fork() ) )
    { // then, child process

        int n =0;
        for(;n<3;n++)
        {

            locksem = semget(key1, nsems, semflg);   /* open-create locksem*/
            emptysem = semget(key2, nsems, semflg);
            fullsem = semget(key3, nsems, semflg);

            semop(fullsem,&oplock,1);  /* check filled slots */
            semop(locksem,&oplock,1);      /* lock shared buffer*/

            // itx= remove_item();
            /* remove an item from buffer */
            int i = 0;
            for (;i<10; i++)
            {
                rem[i] = data[i];
            } // end for

            bzero(buffer,10);
            bzero(data,strlen(data));

            /* detach from the segment: */
            if (shmdt(data) == -1)
            {
                error( "shmdt" );
            } // error() does not return

            // implied else, shmdt successful

            semop(locksem,&opunlock,1);  /* unlock the buffer */
            semop(emptysem,&opunlock,1);  /* increment emptysem*/
            //consume_item(itx);

            int sum = 0;
            for(i =0; i<10; i++)
            {
                sum += rem[i];
            } // end for

            printf("the sum is:%d \n", sum);
        } // end while
    }

    else
    { // else parent process
        creatmemory();

        int n =0;
        for(;n<3;n++)
        {
            locksem = semget(key1, nsems, semflg);   /* open-create locksem*/
            emptysem = semget(key2, nsems, semflg);
            fullsem = semget(key3, nsems, semflg);

            bzero(buffer,10);
            int i;
            for(i =0; i<10; i++)
            {
                buffer[i] = i;
            } // end for

            semop(emptysem,&oplock,1);  /* check empty slots */
            semop(locksem,&oplock,1);      /* lock shared buffer*/

            /* insert item into the buffer */
            strncpy(data, buffer, strlen(buffer));
            printf("done \n");

            semop(locksem,&opunlock,1);  /* unlock the buffer */
            semop(fullsem,&opunlock,1);  /* increment fullsem*/

            sleep(10);
        } // end for
    } // end if

    return(0);
} // end function: main


void creatmemory()
{
    /* make the key: */
    if ((key = ftok("/tmp",1)) == -1)
    {
        error( "ftok" ); // error does not return
    }

    // implied else, ftok successful

    /* connect to (and possibly create) the segment: */
    if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1)
    {
        error( "shmget" ); // error does not return
    }

    // implied else, shmget successful

    /* attach to the segment to get a pointer to it: */
    data = shmat(shmid, (void *)0, 0);

    if (data == (char *)(-1))
    {
        error( "shmat" ); // error does not return
    }

    // implied else, shmat successful
} // end function: creatmemory


void error(char *msg)
{
    perror(msg);
    exit(0);
} // end function: error

I would suggest using a mutex rather than a semaphore for critical code/data protection.

BTW: unless destroyed, a semaphore is around forever.

In Linux, they become part of the /proc directory tree.

Upvotes: 2

Related Questions