2018-4-26-Linux进程通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tryantking/article/details/80105961

LInux实现 System V 信号量进程通信(共享内存)

一、利用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
  1. id 与 key 是不一样的,id是由系统随机生成的,用户对于 id 没有任何操作的权限,但是密匙 key 就可以由函数调用,对共享内存的位置等代表性地方进行标注。

二、基本自定义函数

//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;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页