• system v共享内存与信号量综合


    ipc.h

    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/shm.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #ifndef _IPC_H_
    #define _IPC_H_
    
    union semun {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
        
        struct seminfo *_buf;
    };
    
    int sem_create(key_t key);
    int sem_open(key_t key);
    
    int sem_p(int semid);
    int sem_v(int semid);
    int sem_d(int semid);
    int sem_setval(int semid, int val);
    int sem_getval(int semid);
    int sem_getmode(int semid);
    int sem_setmode(int semid, char* mode);
    
    #endif //_IPC_H_

    ipc.c

    #include "ipc.h"
    
    int sem_create(key_t key)
    {
        int semid = semget(key,1,0666 | IPC_CREAT | IPC_EXCL);
        if (-1 == semid)
        {
            printf("sem create faild
    ");
            exit(1);
        }
        return semid;
    }
    int sem_open(key_t key)
    {
        int semid = semget(key,0,0);
        if (-1 == semid)
        {
            printf("sem open faild
    ");
            exit(1);
        }
        return semid;
    }
    
    int sem_p(int semid)
    {
        struct sembuf sb = {0,-1,0};
        int ret = semop(semid,&sb,1);
        if(-1 == ret)
        {    
            printf("sem p faild
    ");
            exit(1);
        }
        return ret;
    }
    int sem_v(int semid)
    {
        struct sembuf sb = {0,1,0};
            int ret = semop(semid,&sb,1);
            if(-1 == ret)
            {
                    printf("sem v faild
    ");
                    exit(1);
            }
            return ret;
    }
    int sem_d(int semid)
    {
        int ret = semctl(semid, 0, IPC_RMID, 0);
        return ret;
    }
    int sem_setval(int semid, int val)
    {
        union semun su;
        su.val = val;
        int ret = semctl(semid, 0, SETVAL,su);
        if (-1 == ret)
        {
            printf("sem setval faild
    ");
            exit(1);
        }
        return ret;
    }
    int sem_getval(int semid)
    {
        int ret = semctl(semid, 0, GETVAL,0);   
            if (-1 == ret)
            {
                    printf("sem getval faild
    ");
                    exit(1);
            }
            return ret;
    }
    int sem_getmode(int semid)
    {
        union semun su;
        struct semid_ds sem;
        su.buf = &sem;
        int ret = semctl(semid , 0 , IPC_STAT, su);
        if (-1 == ret)
        {
            printf("sem getmode failed
    ");
            exit(1);
        }
        printf("current permissions is %o
    ",su.buf->sem_perm.mode);
        return ret;
    }
    int sem_setmode(int semid, char* mode)
    {
        union semun su;
            struct semid_ds sem;
            su.buf = &sem;
            int ret = semctl(semid , 0 , IPC_STAT, su);
            if (-1 == ret)
            {
                    printf("sem getmode failed
    ");
                    exit(1);
            }
            printf("current permissions is %o
    ",su.buf->sem_perm.mode);
        sscanf(mode ,"%o",(unsigned int*)&su.buf->sem_perm.mode);
        ret = semctl(semid , 0 , IPC_STAT, su);
            if (-1 == ret)
            {
                    printf("sem getmode failed
    ");
                    exit(1);
            }
        printf("permissios update...
    ");
        
        return ret;
    }

    shmfifo.h

    #include "ipc.h"
    
    #ifndef _SHM_FIFO_H_
    #define _SHM_FIFO_H_
    
    
    typedef struct shmfifo shmfifo_t;
    typedef struct shmhead shmhead_t;
    
    typedef struct stu
    {
            char name[32];
            int age;
    }STU;
    
    struct shmhead
    {
        unsigned int blksize;        // 块大小
        unsigned int blocks;        // 总块数
        unsigned int rd_index;        // 读索引
        unsigned int wr_index;        // 写索引
    };
    
    struct shmfifo
    {
        shmhead_t *p_shm;            // 共享内存头部指针
        char *p_payload;            // 有效负载的起始地址
    
        int shmid;                    // 共享内存ID
        int sem_mutex;                // 用来互斥用的信号量
        int sem_full;                // 用来控制共享内存是否满的信号量
        int sem_empty;                // 用来控制共享内存是否空的信号量
    };
    
    shmfifo_t* shmfifo_init(int key, int blksize, int blocks);//初始化
    void shmfifo_put(shmfifo_t *fifo, const void *buf);//添加数据到环形缓冲区
    void shmfifo_get(shmfifo_t *fifo, void *buf);//从缓冲区中取数据
    void shmfifo_destroy(shmfifo_t *fifo);//释放共享内存的环形缓冲区
    
    #endif /* _SHM_FIFO_H_ */

    shmfifo.c

    #include "shmfifo.h"
    #include <assert.h>
    
    shmfifo_t* shmfifo_init(int key, int blksize, int blocks)
    {
        //分配内存空间
        shmfifo_t *fifo = (shmfifo_t *)malloc(sizeof(shmfifo_t));
        assert(fifo != NULL);
        memset(fifo, 0, sizeof(shmfifo_t));
    
        int shmid;
        shmid = shmget(key, 0, 0);
        int size = sizeof(shmhead_t) + blksize*blocks;
        if (shmid == -1)
        {//创建共享内存
            fifo->shmid = shmget(key, size, IPC_CREAT | 0666);
            if (fifo->shmid == -1)
                exit(1);
    
            fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, 0);
            if (fifo->p_shm == (shmhead_t*)-1)
                exit(1);
    
            fifo->p_payload = (char*)(fifo->p_shm + 1);
    
        //进行字段初始化
        fifo->p_shm->blksize = blksize;
        fifo->p_shm->blocks = blocks;
        fifo->p_shm->rd_index = 0;
        fifo->p_shm->wr_index = 0;
    
            fifo->sem_mutex = sem_create(key);
            fifo->sem_full = sem_create(key+1);
            fifo->sem_empty = sem_create(key+2);
    
            sem_setval(fifo->sem_mutex, 1);
            sem_setval(fifo->sem_full, blocks);
            sem_setval(fifo->sem_empty, 0);
        }
        else
        {//打开共享内存
            fifo->shmid = shmid;
            fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, 0);
            if (fifo->p_shm == (shmhead_t*)-1)
                exit(1);
    
            fifo->p_payload = (char*)(fifo->p_shm + 1);
    
            fifo->sem_mutex = sem_open(key);
            fifo->sem_full = sem_open(key+1);
            fifo->sem_empty = sem_open(key+2);
        }
    
        return fifo;
    }
    
    void shmfifo_put(shmfifo_t *fifo, const void *buf)
    {
        sem_p(fifo->sem_full);
        sem_p(fifo->sem_mutex);
    
        //生产产品
        memcpy(fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->wr_index, 
            buf, fifo->p_shm->blksize);
        fifo->p_shm->wr_index = (fifo->p_shm->wr_index + 1) % fifo->p_shm->blocks;
    
        sem_v(fifo->sem_mutex);
        sem_v(fifo->sem_empty);
    }
    
    void shmfifo_get(shmfifo_t *fifo, void *buf)
    {
        sem_p(fifo->sem_empty);
        sem_p(fifo->sem_mutex);
    
        memcpy(buf, fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->rd_index, 
            fifo->p_shm->blksize);
        fifo->p_shm->rd_index = (fifo->p_shm->rd_index + 1) % fifo->p_shm->blocks;
        sem_v(fifo->sem_mutex);
        sem_v(fifo->sem_full);
    }
    
    void shmfifo_destroy(shmfifo_t *fifo)
    {
        //删除创建的信息量集
        sem_d(fifo->sem_mutex);
        sem_d(fifo->sem_full);
        sem_d(fifo->sem_empty);
    
        //删除共享内存
        shmdt(fifo->p_shm);//删除共享内存头部
        shmctl(fifo->shmid, IPC_RMID, 0);//删除整个共享内存
        
        //释放fifo的内存 
        free(fifo);
    }

    shmfifo_send.c

    #include "shmfifo.h"
    /*
    typedef struct stu
    {
        char name[32];
        int age;
    }STU;
    */
    int main(void)
    {
        shmfifo_t *fifo = shmfifo_init(1234,sizeof(STU),3);
        
        STU s;
        memset(&s, 0, sizeof(STU));
        s.name[0] = 'A';
        int i;
        for(i=0;i<10;i++)
        {
            s.age = 10 + i;
            shmfifo_put(fifo,&s);
            s.name[0] = s.name[0] + 1;
            printf("send ok
    ");
        }
        return 0;
    }

    shmfifo_recv.c

    #include "shmfifo.h"
    /*
    typedef struct stu
    {
            char name[32];
            int age;
    }STU;
    */
    int main(void)
    {
            shmfifo_t *fifo = shmfifo_init(1234,sizeof(STU),3);
    
            STU s;
            memset(&s, 0, sizeof(STU));
           
            int i;
            for(i=0;i<10;i++)
            {
                    shmfifo_get(fifo,&s);
                    printf("name = %s, age = %d
    ",s.name,s.age);
            }
            return 0;
    }

    shmfifo_free.c

    #include "shmfifo.h"
    
    int main(void)
    {
        shmfifo_t *fifo = shmfifo_init(1234,sizeof(STU),3);
        shmfifo_destroy(fifo);
        return 0;
    }

    Makefile

    .PHONY:clean all
    CC=gcc
    CFLAGS=-Wall -g
    BIN= shmfifo_send shmfifo_recv shmfifo_free
    OBJS1=shmfifo_send.o shmfifo.o ipc.o
    OBJS2=shmfifo_recv.o shmfifo.o ipc.o
    OBJS3=shmfifo_free.o shmfifo.o ipc.o
    all:$(BIN)
    %.o:%.c
        $(CC) $(CFLAGS) -c $< -o $@
    shmfifo_send:$(OBJS1)
        $(CC) $(CFLAGS) $^ -o $@
    shmfifo_recv:$(OBJS2)
        $(CC) $(CFLAGS) $^ -o $@
    shmfifo_free:$(OBJS3)
        $(CC) $(CFLAGS) $^ -o $@
    
    clean:
        rm -f *.o $(BIN)
  • 相关阅读:
    我来了
    性能分析:处理器、磁盘I/O、进程、网络分析方法 http://www.cnblogs.com/fnng/archive/2012/10/30/2747246.html
    jvisualvm监控服务器状态
    linux下常用监控命令
    app 常见网络性能
    native app ->hybrid app->web app的发展
    JMeter远程启动客户端总是不通的原因
    java机制
    webbench,linux下并发测试工具
    操作数数据类型 ntext 对于 max 运算符无效
  • 原文地址:https://www.cnblogs.com/Malphite/p/7786711.html
Copyright © 2020-2023  润新知