UNIX环境高级编程学习之第十五章进程间通信 - 系统V 共享内存使用(使用信号灯保护共享内存)

UNIX环境高级编程学习之第十五章进程间通信 - 系统V 共享内存使用(使用信号灯保护共享内存)

 

 

 

CSDN Blog又出问题了,不能插入代码了。只能这么粘贴了。

 

 



/* User:Lixiujie      
 * Date:20100915
 * Desc:系统V 共享内存使用(使用信号灯保护共享内存)
 * File:shared_memory.c
 * System:Ubuntu 64bit
 * gcc shared_memory.c -o shm
 */ 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
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 */   //test!!
    void *__pad;
};
/* 取当前文件路径 */ 
char* getCurrentFilePath(char *szCurrentFilePath);
/* 创建信号灯 */
int CreateSemaphore(const char* szFilePath, int id);
/* 申请使用资源 */
int PSemaphore(int semID);
/* 释放资源 */
int VSemaphore(int semID);
/* 删除信号量*/
int RemoveSemaphore(int semID);

/* 创建共享内存 */
int CreateSharedMemory(const char* szFilePath, int id, int iSize);
/* 附加共享内存 */
void* AttachSharedMemory(int shmID);
/* 分离共享内存 */
int DetachSharedMemory(void* pData);
/* 共享内存读操作 */
void* ReadSharedMemory(int iShmStart,int iShmLen, void* pData, int semID,int shmID);
/* 共享内存写操作 */
void* WriteSharedMemory(int iShmStart, int iLen, void* pData, int semID,int shmID);
/* 删除共享内存 */
int RemoveSharedMemory(int shmID);

/* 取当前文件路径 */ 
char* getCurrentFilePath(char *szCurrentFilePath){ 
    char szBuf[256] = { 0x00 }; 
    strcpy(szBuf, __FILE__); 
    if (strstr(szBuf, "/") == NULL){ 
        memset(szBuf, 0x00, sizeof(szBuf)); 
        strcpy(szBuf, getenv("PWD")); 
        strcat(szBuf, "/"); 
        strcat(szBuf, __FILE__); 
    } 
    strcpy(szCurrentFilePath, szBuf); 
    return szCurrentFilePath; 
}

/* 创建信号灯 */
int CreateSemaphore(const char* szFilePath, int id){
    int i;
    /* 信号灯的Key */
    key_t semKey;
    union semun arg;
    int semID;
    int tmpErrno;
    /* 等待信号集初始化完成尝试次数 */
    int iMaxTries = 3;
    /* 信号集初始化完成标志 */
    int iInitOk = 0;
    /* 当前信号集信息, 内核分配给每个信号集的结构 */
    struct semid_ds semCurrInfo;
    /* 产生key */ 
    semKey = ftok(szFilePath, id);
    if (-1 == semKey){ 
        perror("CreateSemaphore() ftok() is failed!/n"); 
        exit(1); 
    }
     /* 创建一个信号量集,只包含一个信号 */
    semID = semget(semKey, 1, IPC_CREAT|IPC_EXCL|00666);
    if (-1 == semID){
        tmpErrno = errno;
        if (EEXIST == tmpErrno){
            perror("CreateSemaphore() semget() is already exists!/n");
            /* 获取一个信号量集,只包含一个信号 */
            semID = semget(semKey, 1, IPC_CREAT|00666);
            if (-1 == semID){
                perror("CreateSemaphore() semget() semget() is failed!/n");
                exit(1);
            }
            arg.buf = &semCurrInfo;
            for (i = 0;i < iMaxTries;i++){
                if (semctl(semID, 0, IPC_STAT, arg) == -1){
                    perror("CreateSemaphore() semget() semget() is failed!/n");
                }else{
                    /* sem_otime:最后semop修改时间,创建初始值为0 */
                    if (arg.buf->sem_otime != 0){
                        iInitOk = 1;
                        break;
                    }
                }
                sleep(1);
            }
            if (0 == iInitOk){
                /* 第一个创建semaphore进程没有初始化完成或刚好初始化完成,
                 * 本次要初始化一下,否则无法下面的工作。
                 */
                arg.val = 1;/* 资源数 */
                if (semctl(semID, 0, SETVAL, arg) == -1){
                    perror("CreateSemaphore() semget() semctl() is failed/n");
                    exit(-1);
                }
            }
        } else {
            perror("CreateSemaphore() semget() is failed!/n");
            exit(1);
        }
       
    }else{
         arg.val = 1;/* 资源数 */
        if (semctl(semID, 0, SETVAL, arg) == -1){
            perror("CreateSemaphore() semctl() is failed/n");
            exit(-1);
        }
    }
    return semID;
}

/* 申请使用资源 */
int PSemaphore(int semID){
    struct sembuf sops={0, -1, SEM_UNDO};
    return semop(semID, &sops, 1);
}

/* 释放资源 */
int VSemaphore(int semID){
    struct sembuf sops={0, 1, SEM_UNDO};
    return semop(semID, &sops, 1);
}

/* 创建共享内存 */
int CreateSharedMemory(const char* szFilePath, int id, int iSize){
    /* 共享内存的Key */
    key_t shmKey;
    int shmID;
    int tmpErrno;
    /* 产生key */ 
    shmKey = ftok(szFilePath, id);
    if (-1 == shmKey){ 
        perror("CreateSharedMemory() ftok() is failed!/n"); 
        exit(1); 
    }
    /* 获取一个共享内存 */
    shmID = shmget(shmKey, iSize, IPC_CREAT|IPC_EXCL|00666);
    if (-1 == shmID){
        tmpErrno = errno;
        if (EEXIST == tmpErrno){
            perror("CreateSharedMemory() shmget() is already exists!/n");
            /* 获取一个共享内存 */
            shmID = shmget(shmKey, iSize, IPC_CREAT|00666);
            if (-1 == shmID){
                perror("CreateSharedMemory() shmget() shmget() is failed!/n");
                exit(1);
            }
        } else {
            perror("CreateSharedMemory() shmget() is failed!/n");
            exit(1);
        }
    }else{
        /* 初始化 */
        char* pC = (char*)AttachSharedMemory(shmID);
        if (pC == NULL){
            perror("CreateSharedMemory() AttachSharedMemory() is failed!/n");
            exit(1);
        }
        memset(pC, '/0',iSize);
        if (DetachSharedMemory(pC) != 0){
            perror("CreateSharedMemory() DetachSharedMemory() is failed!/n");
            exit(1);
        }
    }
    return shmID;
}

/* 附加共享内存 */
void* AttachSharedMemory(int shmID){
    char* pC;
    pC = (char*)shmat(shmID, NULL, 0);
    if (NULL == pC || pC == (char*)-1 ){
        return (void*)NULL;
    }
    return (void*)pC;
}

/* 分离共享内存 */
int DetachSharedMemory(void* pData){
    return shmdt(pData);
}

/* 共享内存读操作 */
void* ReadSharedMemory(int iShmStart,int iShmLen, void* pData, int semID,int shmID){
    char *pC;
    int ret;
    ret = PSemaphore(semID);
    if (ret != 0){
        perror("ReadSharedMemory() PSemaphore() is failed!");
        return NULL;
    }
    pC = (char*)AttachSharedMemory(shmID);
    if (pC != NULL){
        memcpy(pData, pC+iShmStart, iShmLen);
        DetachSharedMemory(pC);
    }else{
        perror("ReadSharedMemory() AttachSharedMemory() is failed!");
        VSemaphore(semID);
        return NULL;
    }
    ret = VSemaphore(semID);
    if (ret != 0){
        perror("ReadSharedMemory() VSemaphore() is failed!");
        return NULL;
    }
    return pData;
}

/* 共享内存写操作 */
void* WriteSharedMemory(int iShmStart, int iLen, void* pData, int semID,int shmID){
    char *pC;
    int ret;
    ret = PSemaphore(semID);
    if (ret != 0){
        perror("WriteSharedMemory() PSemaphore() is failed!");
        return NULL;
    }
    pC = (char*)AttachSharedMemory(shmID);
    if (pC != NULL){
        memcpy(pC+iShmStart, pData, iLen);
        DetachSharedMemory(pC);
    }else{
        perror("WriteSharedMemory() AttachSharedMemory() is failed!");
        VSemaphore(semID);
        return NULL;
    }
    ret = VSemaphore(semID);
    if (ret != 0){
        perror("WriteSharedMemory() VSemaphore() is failed!");
        return NULL;
    }
    return pData;
}

/* 删除共享内存 */
int RemoveSharedMemory(int shmID){
    return shmctl(shmID, IPC_RMID, NULL);
}

/* 删除信号量*/
int RemoveSemaphore(int semID){
    return semctl(semID, 0, IPC_RMID);
}

int main(int argc, char * argv[]){
    char *pC;
    char szFilePath[256] = {  '/0' };
    char szData[256] = { 0x00 };
    getCurrentFilePath(szFilePath);
    int semID; /* 信号量,二值信号灯 相当于进程间互斥锁 */
    int shmID; /* 共享内存 */
    /* 创建或获取信号量 */
    semID = CreateSemaphore(szFilePath, 0);
    /* 创建或获取共享内存 */
    shmID = CreateSharedMemory(szFilePath, 0, 4096);
    /* 读共存内存数据 */
    memset(szData, 0x00, sizeof(szData));
    pC = ReadSharedMemory(0, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() ReadSharedMemory() is failed!");
        exit(-1);
    }
    printf("Data_1:%s/n", szData);
    memset(szData, 0x00, sizeof(szData));
    pC = ReadSharedMemory(300, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() ReadSharedMemory() is failed!");
        exit(-1);
    }
    printf("Data_2:%s/n", szData);
    /* 写共存内存数据 */
    memset(szData, 0x00, sizeof(szData));
    strcpy(szData, "Hello lixiujie!/0");
    pC = WriteSharedMemory(0, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() WriteSharedMemory() is failed!");
        exit(-1);
    }
    strcpy(szData, "Hello wanzhenjie!/0");
    pC = WriteSharedMemory(300, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() WriteSharedMemory() is failed!");
        exit(-1);
    }
   
    sleep(20);

    /* 读共存内存数据 */
    memset(szData, 0x00, sizeof(szData));
    pC = ReadSharedMemory(0, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() ReadSharedMemory() is failed!");
        exit(-1);
    }
    printf("Data_1:%s/n", szData);
    memset(szData, 0x00, sizeof(szData));
    pC = ReadSharedMemory(300, sizeof(szData) - 1, szData, semID, shmID);
    if (NULL == pC){
        perror("main() ReadSharedMemory() is failed!");
        exit(-1);
    }
    printf("Data_2:%s/n", szData);

    RemoveSharedMemory(shmID);
    RemoveSemaphore(semID);
    return 0;
}

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值