マルチプロセス+共有メモリ+信号量統合例
26930 ワード
具体的な説明はコメントを見てください。また信号量のノッチについては参照できます。http://os.51cto.com/art/201311/418977_all.httm
http://blog.csdn.net/killmice/article/details/41516399
テストフレーム
ヘッダファイル
ヘッダファイル
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)