以下爲head.h頭文件,包含其中的彩色打印中的對應ASCII碼
#ifndef __HEAD_H_
#define __HEAD_H_
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/sem.h>
#define NONE "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
#define WHITE "\033[1;37m"
#define PrintERROR(str,ret)\
if(-1 == ret)\
{\
perror(str);\
exit(-1);\
}
#endif
以下爲對應的共享內存通訊的簡單代碼shm_sem.c
#include"head.h"
#define SHM_SIZE 1024*4 //4K對齊
#define pathname "." //當前目錄
#define proj_id 888
static int create_sem(void);
static int init_sem(int semid);
static int DestroySem(int semid);
static int create_shm(void);
char * at_addr(int shmid);
static int Delete_at_addr(char *shmaddr);
static int DestroyShm(int shmid);
static int child_pv_opration(char *buf,int semid);
static int father_pv_opration(char *buf,int semid);
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;
/******************************************************************************
Function: create_sem
Description: 創建信號量,並獲得ID
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int create_sem(void)
{
key_t sem_key;
//創建2個信號量 int semget(key_t key, int nsems, int semflg);
sem_key = semget(sem_key,2,IPC_CREAT|0664);
PrintERROR("semget", sem_key);
return sem_key;
}
/******************************************************************************
Function: init_sem
Description: 給兩個信號量設置初始值
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int init_sem(int semid)
{
//int semctl(int semid, int semnum, int cmd, ...);
int ret = 0;
//設置初始值0
semun_t semval;
semval.val = 0;
//給編號爲0的信號量設置初始值
ret = semctl(semid,0,SETVAL,semval);
PrintERROR("semctl", ret);
//給編號爲1的信號量設置初始值
semctl(semid,1,SETVAL,semval);
PrintERROR("semctl", ret);
}
/******************************************************************************
Function: DestroySem
Description: 刪除信號量
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int DestroySem(int semid)
{
int ret =0;
ret =semctl(semid,0,IPC_RMID);
PrintERROR("semctl", ret);
}
/******************************************************************************
Function: create_shm
Description: 創建共享內存
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int create_shm(void)
{
//key_t ftok(const char *pathname, int proj_id);
int shm_id = 0;
key_t key = ftok(pathname,proj_id);
PrintERROR("ftok", key);
//int shmget(key_t key, size_t size, int shmflg);
shm_id = shmget(key,SHM_SIZE,IPC_CREAT|0666);
PrintERROR("shmget", shm_id);
return shm_id;
}
/******************************************************************************
Function: at_addr
Description: 映射共享內存
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
char * at_addr(int shmid)
{
//void *shmat(int shmid, const void *shmaddr, int shmflg);
return shmat(shmid,NULL,0);
}
/******************************************************************************
Function: Delete_at_addr
Description: 解除共享內存的映射
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int Delete_at_addr(char *shmaddr)
{
//int shmdt(const void *shmaddr);
return shmdt(shmaddr);
}
/******************************************************************************
Function: DestroyShm
Description: 刪除共享內存
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int DestroyShm(int shmid)
{
//int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl(shmid,IPC_RMID,NULL);
}
//struct sembuf{
// unsigned short sem_num; /* semaphore number */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//};
/******************************************************************************
Function: child_pv_opration
Description:
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int child_pv_opration(char *buf,int semid)
{
struct sembuf sempv;
int ret = 0;
while(1)
{
printf(GREEN"child>>>>>>"NONE);
fflush(stdout);
//寫操作
fgets(buf,SHM_SIZE,stdin);
//進行V操作
sempv.sem_num = 0;
sempv.sem_op = +1;
sempv.sem_flg = 0;
//int semop(int semid, struct sembuf *sops, unsigned nsops);
ret = semop(semid,&sempv,1);
PrintERROR("semop", ret);
//對第二個信號量進行P操作
sempv.sem_num = 1;
sempv.sem_op = -1;
sempv.sem_flg = 0;
ret =semop(semid,&sempv,1);
PrintERROR("semop", ret);
//讀
printf(YELLOW"from father:%s\n",buf);
}
}
/******************************************************************************
Function: father_pv_opration
Description:
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
static int father_pv_opration(char *buf,int semid)
{
struct sembuf sempv;
int ret = 0;
while(1)
{
//對第二個信號量進行P操作
sempv.sem_num = 0;
sempv.sem_op = -1;
sempv.sem_flg = 0;
ret =semop(semid,&sempv,1);
PrintERROR("semop", ret);
//讀
printf(YELLOW"from child:%s\n",buf);
printf(GREEN"father>>>>>>"NONE);
fflush(stdout);
//寫操作
fgets(buf,SHM_SIZE,stdin);
//進行V操作
sempv.sem_num = 1;
sempv.sem_op = +1;
sempv.sem_flg = 0;
//int semop(int semid, struct sembuf *sops, unsigned nsops);
ret = semop(semid,&sempv,1);
PrintERROR("semop", ret);
}
}
/******************************************************************************
Function: main
Description: 主函數入口,實現兩個進程間的共享內存通訊
INPUT:
OUTPUT:
Return:
Revision:
1. Author: linsen
Date: 2018/4/03
Changes: First create
******************************************************************************/
int main(int argc, const char * argv [ ])
{
//創建共享內存
int shmid = create_shm();
//創建信號量
int semid = create_sem();
//給信號量設置初始值
init_sem(semid);
//創建兩個進程,子進程進行共享內存的寫操作,父進程進行讀操作並銷燬
pid_t pid;
pid = fork();
PrintERROR("fork", pid);
if(0 == pid)//child
{
char *buf =at_addr(shmid);
if(buf == (void *)-1)
{
perror("shmat");
exit(-1);
}
child_pv_opration(buf,semid);
Delete_at_addr(buf);
}
else if(pid >0)//father
{
char *buf =at_addr(shmid);
if(buf == (void *)-1)
{
perror("shmat");
exit(-1);
}
father_pv_opration(buf,semid);
//解除共享內存的映射
Delete_at_addr(buf);
waitpid(pid,NULL,0);
//刪除共享內存
DestroyShm(shmid);
//刪除信號量
DestroySem(semid);
}
return 0;
}
編譯環境爲linux的使用gcc編譯.
gcc shm_sem.c -o shm_sem生成可執行文件shm_sem.