简体   繁体   English

带有fork和共享内存的C信号量中的POSIX,

[英]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();


}

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. 在Linux中,它们成为/ proc目录树的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM