Posted
: April 26, 2018
Status
:
Completed
Tags
:
Categories
:
###一、利用System V实现进程通信所需要的库
//common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h> //输入输出的标准库函数
#include <stdlib.h> //动态内存的分配库函数
#include <string.h> //宏、内存处理库函数
#include <sys/stat.h> //定义函数fstat(),latat(),stat()返回数据的结构库函数
#include <fcntl.h> //文件控制库函数
#include <pthread.h> //线程控制库函数
#include <semaphore.h> //信号量库函数
#include <sys/types.h> //数据类型的库函数
#include <unistd.h> //对于系统调用的库函数
#include <sys/ipc.h> //进程间进行通信访问的库函数
#include <sys/shm.h> //共享内存控制库函数
static const char * MUTEX_NAME = "mutex_shm";
static const char * FULL_NAME = "full_shm";
//static const char * PATH_NAME = "tmp/shmtemp";
//constant define
#define SHM_SIZE 1024
#define KEY_NUM 1000
/*
key_t GetKey(const char * pathname);
*/
int GetShmId(key_t key);
/*
* create mutex + semaphore
* init those value
*/
void SemInit();
void SemDestroy();
void P(sem_t *sem);
void V(sem_t *sem);
#endif
//common.c
#include "common.h"
int GetShmId(key_t key)
{
int shmid;
shmid = shmget(key,SHM_SIZE,IPC_CREAT|0666);//如果内核中不存在键值与key相等的共享内存,则新建一个消息队列;如果存在这样的共享内存则报错
if(shmid < 0) //失败的话会返回-1
{
perror("Receiver: Shmget Error");
exit(EXIT_FAILURE);
}
return shmid; //成功就返回共享内存的表示符
}
void SemInit()
{
if((sem_open(MUTEX_NAME,O_CREAT,0644,1)) < 0) //初始化并打开一个已命名的信号量
{
perror("sem_open"); //将错误输出到屏幕
exit(EXIT_FAILURE);
}
if((sem_open(FULL_NAME,O_CREAT,0644,0)) < 0){
perror("sem_open");
exit(EXIT_FAILURE);
}
}
void SemDestroy()
{
sem_t * mutexPtr = sem_open(MUTEX_NAME,O_CREAT);
sem_t * fullPtr= sem_open(FULL_NAME,O_CREAT);
/* Destroy mutex */
sem_close(mutexPtr); // int sem_close(sem_t *sem);
sem_unlink(MUTEX_NAME); // int sem_unlink(const char *name);
/* Destory full*/
sem_close(fullPtr); //关闭信号量
sem_unlink(FULL_NAME); //从系统中删除信号量
}
void P(sem_t *semPtr)
{
sem_wait(semPtr); //int sem_wait(sem_t *sem);
}
void V(sem_t *semPtr)
{
sem_post(semPtr); //int sem_post(sem_t *sem);
}
//init.c
#include "common.h"
int main(int argc, char const *argv[])
{
key_t key;
int semid; //信号量 id
int shmid; //共享内存 id
/* Create key*/
key = KEY_NUM; //共享内存密匙
/* Initialize Semaphore*/
SemInit(); //初始化信号量
/* TODO Initialize Shared Memory*/
GetShmId(key); //获得共享内存的 id
printf("End of initialize\n");
return 0;
}
//sender.c
#include "common.h"
#include <stdio.h>
//key
key_t key;
//shared memory
int shmid;
char * shmptr; //共享内存区的数据
char input[SHM_SIZE];
//semaphore
sem_t * full;
sem_t * mutex;
//semaphore
void Init()
{
key = KEY_NUM; //初始化密匙
shmid = GetShmId(key); // 初始化共享内存id
shmptr = shmat(shmid,NULL,0); // 刚刚创建的共享内存需要shmat函数启动才能被访问
//semaphore init
full = sem_open(FULL_NAME,O_CREAT);
mutex = sem_open(MUTEX_NAME,O_CREAT);
}
void SaveMessage()
{
P(mutex);
strcpy(shmptr,input); //将要发送的数据复制到共享内存区域
V(mutex);
V(full);
}
int main(int argc, char const *argv[])
{
Init();
/*waiting for user to input message*/
fgets(input, 1024, stdin); //从shell中获得我们需要输入的句子
SaveMessage();
printf("Sender: Process End\n");
return 0;
}
//receiver.c
#include "common.h"
//key
key_t key;
//shared memory
int shmid;
char * shmptr;
char result[SHM_SIZE];
//semaphore
sem_t * full;
sem_t * mutex;
//semaphore
void Init()
{
key = KEY_NUM; //init key
shmid = GetShmId(key); // init shared memory
shmptr = shmat(shmid,NULL,0); // attach segement to vitural ...?
//semaphore init
full = sem_open(FULL_NAME,O_CREAT);
mutex = sem_open(MUTEX_NAME,O_CREAT);
}
void ReadMessage()
{
P(full);
P(mutex);
strcpy(result,shmptr); //从共享内存中获得我们在sender中输入的句子
V(mutex);
}
int main(int argc, char const *argv[])
{
Init();
/*waiting for user to input message*/
ReadMessage();
printf("Receiver : message is %s\n",result);
SemDestroy();
printf("Receiver : Process End \n");
return 0;
}
Comments
😅 Commenting is disabled on this post.