マルチプロセス+共有メモリ+信号量統合例


具体的な説明はコメントを見てください。また信号量のノッチについては参照できます。http://os.51cto.com/art/201311/418977_all.httm
http://blog.csdn.net/killmice/article/details/41516399
テストフレーム
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "myipc_sem.h"
#include "myipc_shm.h"

void Test(int var)
{

  int cnt = 0;
  int ret = 0;
  int shmdl = 0;
  int *addr = NULL;
  key_t key ;
  int semid = 0;

  //     key  /       
  key = ftok("./",'a');

  //       --    1    
  ret = sem_open(key, &semid);
  if(ret == SEMERR_ENOXIST)
  {
    ret = sem_create(key, &semid);
    if(ret != 0)
    {
      printf("sem_create err
"
); return -1; } } //sem_p(semid);//p printf("Aloha!Fork()....%d
"
,var); ret = IPC_CreatShm("./", sizeof(int), &shmdl); if(ret != 0) { printf("IPC_CreatShm err
"
); return -1; } ret = IPC_MapShm(shmdl,(void**)&addr); cnt = ++(*addr); printf("cnt:%d
"
,cnt); ret = IPC_UnMapShm(addr);// //sem_v(semid);//v printf("child: %d exit!
=================================================================
"
,getpid()); } int main() { int loop_num = 0; int proc_num = 0; int i = 0,j = 0; pid_t pid ; int ret = 0; int shmdl = 0; key_t key = 0; int semid = 0; signal(SIGCHLD,SIG_IGN); printf("Input the procnum:
"
); scanf("%d",&proc_num); printf("Input the loopnum:
"
); scanf("%d",&loop_num); // -- key , // , -- // ( ) // ID-- // , , key -- ret = IPC_CreatShm("./", sizeof(int), &shmdl); if(ret != 0) { printf("IPC_CreatShm err
"
); return -1; } // key / key = ftok("./",'a'); // -- 1 // -- // key , , // ret = sem_open(key, &semid); if(ret == SEMERR_ENOXIST) { ret = sem_create(key, &semid); if(ret != 0) { printf("sem_create err
"
); return -1; } } int val= 1; ret = sem_set(semid, val);// -- 1 , 0 if(ret == -1) { printf("sem_set err
"
); return -1; } ret = sem_get(semid, &val);// if(ret != 0) { printf("sem_get err
"
); return -1; } printf("val:%d
"
,val); for(i= 0; i < proc_num;i++) { pid = fork(); if(0 == pid) { sem_p(semid);//p printf("child : %d\tparent : %d
"
,getpid(),getppid());// , init --1 -- PID 1 for(j = 0;j < loop_num;j++) { Test(j); } sem_v(semid);//v // -- fork-- // ,Linux exit(0); // , , shmdt , // ipcs ntach -- //while(1); } } wait(NULL); IPC_DelShm(shmdl); return 0; }
信号量モジュール
ヘッダファイル

#ifndef __MYIPC_SEM_H__
#define __MYIPC_SEM_H__

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SEM_NUM 1

#define SEMERR_BASE 100
#define SEMERR_PARAM (SEMERR_BASE+1)
#define SEMERR_EXIST (SEMERR_BASE+2)
#define SEMERR_ENOXIST (SEMERR_BASE+3)


typedef union semun {
   int              val;    /* Value for SETVAL */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO
                               (Linux-specific) */
}semun_t;

#if 0
typedef struct sembuf{
  unsigned short sem_num;  /* semaphore number */
  short          sem_op;   /* semaphore operation */
  short          sem_flg;  /* operation flags */
}sembuf_t;
#endif

typedef struct sembuf sembuf_t;

int sem_create(key_t key,int *semid);
int sem_open(key_t key,int *semid);
int sem_set(int semid,int val);
int sem_get(int semid,int* val);
int sem_p(int semid);
int sem_v(int semid);

#endif

実現ファイル
#include "myipc_sem.h"

//            
int sem_create(key_t key,int *semid)
{
  int sem_id = 0;
  int ret = 0;

  if(semid == NULL)
  {
    ret = SEMERR_PARAM;
    perror("argv err
"
); return ret; } sem_id = semget(key,SEM_NUM,0666|IPC_CREAT|IPC_EXCL); if(sem_id == -1) { ret = SEMERR_EXIST; perror("semget"); if(errno == EEXIST) { printf("Judge by self..exist
"
); } return ret; } *semid = sem_id; return ret; } // int sem_open(key_t key,int *semid) { int sem_id = 0; int ret = 0; if(semid == NULL) { ret = SEMERR_PARAM; perror("argv err
"
); return ret; } sem_id = semget(key,SEM_NUM,0666); if(sem_id == -1) { if(errno == ENOENT) { printf("Judge by self..exist
"
); ret = SEMERR_ENOXIST; return ret; } } *semid = sem_id; return ret; } // int sem_set(int semid,int val) { int ret = 0; if(semid < 0) { return -1; } semun_t su; su.val = val; ret = semctl(semid,0,SETVAL,su); return ret; } // int sem_get(int semid,int* val) { int ret = 0; if(semid < 0) { return -1; } semun_t su; ret = semctl(semid,0,GETVAL,su);// if(ret == -1)// -1 semctl -- return ret; else// -- 0-- 0 ret = 0; *val = su.val;// return ret; } // p int sem_p(int semid) { int ret = 0; sembuf_t buf = {0,-1,0};// 0 , 0 ret = semop(semid,&buf,1 );// return ret; } // v int sem_v(int semid) { int ret = 0; sembuf_t buf = {0,+1,0};// 0 , 0 ret = semop(semid,&buf,1);// return ret; }
共有メモリモジュール
ヘッダファイル

#ifndef __MYIPC_SHM_H__
#define __MYIPC_SHM_H__

#include 
#include 
#include 

#define _OS_LINUX_

#if defined _OS_LINUX_
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "myipc_shm.h" 

#endif


#ifdef __cplusplus 
extern "C" {
#endif

int IPC_CreatShm(char *shmseedfile, int shmsize, int *shmhdl);

int IPC_MapShm(int shmhdl,void **mapaddr);

int IPC_UnMapShm(void *unmapaddr);

int IPC_DelShm(int shmhdl);


#ifdef __cplusplus
}
#endif
#endif


実現ファイル

#include "myipc_shm.h"

int shmflag = 0;
int shmkey;

/***********************************************************************
      :          
      :    shmname  [in]        ,       
                shmsize  [in]              ;
                shmhdl   [out]        .
     :        0      ; 0     
************************************************************************/
int IPC_CreatShm(char *shmseedfile, int shmsize, int *shmhdl)
{
    if(shmflag == 0)            //         key      
    {
        shmkey = ftok(shmseedfile, 'c');
        if (shmkey == -1)
        {
            perror("ftok");
            return -1;
        }

        shmflag = 1;
    }

    //      
    *shmhdl = shmget(shmkey,shmsize,IPC_CREAT|0666);
    if (*shmhdl == -1)          //    
        return -2;
    return 0;

}
/***********************************************************************
      :          
      :    shmhdl   [in]       
                mapaddr [out]        
     :        0      ; 0     
************************************************************************/
int
IPC_MapShm(int  shmhdl, void  **mapaddr)
{
    void *tempptr = NULL;

    //      
    tempptr = (void *)shmat(shmhdl,0,SHM_RND);
    if (tempptr == (void*)-1)       //        
        return -1;
    *mapaddr = tempptr;         //         

    return 0;
}
/***********************************************************************
      :            
      :    unmapaddr   [in]        
     :        0      ; 0     
************************************************************************/
int IPC_UnMapShm(void *unmapaddr)
{
    int  rv;
    //         
    rv = shmdt((char *)unmapaddr);
    if (rv == -1)           //      
        return -1;

    return 0;
}
/***********************************************************************
      :          
      :    shmhdl   [in]       
     :        0      ; 0     
************************************************************************/
int IPC_DelShm(int shmhdl)
{
    int  rv;
    //      
    rv = shmctl(shmhdl,IPC_RMID,NULL);
    if(rv < 0)              //        
        return -1;
    return 0;
}
Makefileファイル
CC=gcc
CFLAGS=-Wall -g
BIN=app 
.PHONY:clean all 

all:$(BIN)
$(BIN):mulfork.o myipc_sem.o myipc_shm.o
    $(CC) $(CFLAGS) $^ -o $@
%.o:%.c 
    $(CC) $(CFLAGS) -c $^ -o $@

clean:
    rm -f *.o $(BIN)