码迷,mamicode.com
首页 > 其他好文 > 详细

共享内存和信号量

时间:2014-10-30 00:08:04      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:blog   io   ar   for   sp   数据   div   on   log   

1) 获取信号量标识符 int semget(key_t key, int nsems, int flag)
2) 操作信号量(初始化,删除等) int semctl(int semid, int semnum, int cmd, /*union semun*/)
3) 对信号量进行增减操作,在该操作是一个原子操作 int semop(int semid, struct sembuf  semoparray[ ], size_t nops)

sem.h

#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FTOK_FILE "/etc/profile"
#define TEST_FILE "/home/root/sem_file.dat"

#define STR_LEN 32
#define SHM_SIZE 256

union semun
{
        int val;
        struct semid_ds *buf;
        unsigned short *array;
};

typedef struct _tag_shm
{
        char buf[SHM_SIZE];
        unsigned short num;
}shm_t;



int creat_sem(void)
{
    int semid = 0;
    key_t key = ftok(FTOK_FILE,11);

    if(key == -1)
    {
        printf("%s: key =-1!\n",__func__);
        return -1;
    }

    semid = semget(key,1,IPC_CREAT|0666);
    if(semid == -1)
    {
        printf("%s: semid =-1!\n",__func__);
        return -1;
    }

    return semid;
}

int set_semvalue(int semid)
{
    union semun sem_arg;
    sem_arg.val = 1;

    if(semctl(semid,0,SETVAL,sem_arg) == -1)
    {
        printf("%s: can‘t set value for sem!\n",__func__);
        return -1;
    }

    return 0;
}

int sem_p(int semid)
{
    struct sembuf sem_arg;
    sem_arg.sem_num = 0;
    sem_arg.sem_op = -1;
    sem_arg.sem_flg = SEM_UNDO;

    if(semop(semid, &sem_arg,1) == -1)
    {
        printf("%s: can‘t do the sem_p!\n",__func__);
        return -1;
    }

    return 0;
}

int sem_v(int semid)
{
    struct sembuf sem_arg;
    sem_arg.sem_num = 0;
    sem_arg.sem_op = 1;
    sem_arg.sem_flg = SEM_UNDO;

    if(semop(semid, &sem_arg,1) == -1)
    {
        printf("%s: can‘t do the sem_v!\n",__func__);
        return -1;
    }

    return 0;
}

int del_sem(int semid)
{
    if(semctl(semid,0,IPC_RMID) == -1)
    {
        printf("%s : can‘t rm the sem!\n",__func__);
        return -1;
    }

    return 0;
}

 read

#include "sem.h"

int main(void)
{
        int semid,shmid;
        char buf[STR_LEN] = {0};

        int i = 0;
        void * pshm_addr = NULL;
        shm_t *pshm = NULL;

        /*获取信号量标识符*/
        semid = creat_sem( );

        if(semid == -1)
        {
                printf("%s : semid = %d!\n", __func__, semid);
            return -1;
        }

        /*创建信号量之后的,初始化操作*/
        if(set_semvalue(semid))
        {
                printf("%s : set_semvalue failed!\n",__func__);
                return -1;
        }

        /*获取共享内存标识符*/
        shmid = shmget(ftok(FTOK_FILE, 111), sizeof(shm_t), IPC_CREAT|0666);
        if(shmid == -1)
        {
                printf("%s : shmid = %d!\n",__func__, shmid);
                return -1;
        }

        /*当前进程连接该共享内存段*/
        pshm_addr = shmat(shmid, 0 , 0);
        if(pshm_addr == (void *)-1)
        {
                printf("%s : pshm_addr == (void*)0!\n",__func__);
                return -1;
        }

        pshm = (shm_t*)pshm_addr;
        printf("read process semid is %d,shmid is %d!\n", semid,shmid);


        /*让写数据的进程先运行*/
        sleep(4);

        for(; ;)
        {
                /*占用信号量,p操作*/
                if(sem_p(semid))
                {
                        printf("%s : sem_p failed !\n",__func__);
                        return -1;
                }

                printf("enter read process!\n");
                printf("pshm->num is %d!\n",pshm->num);
                printf("pshm->buf is %s", pshm->buf);
                printf("leave read process!\n\n");


                /*释放信号量,v操作*/
                if(sem_v(semid))
                {
                        printf("%s : sem_v failed!\n",__func__);
                        return -1;
                }

                if(!strncmp(pshm->buf, "end", 3))
                        break;

                sleep(2);
        }


        /*删除信号量*/
        if(del_sem(semid))
        {
                printf("%s : del_sem failed!\n", __func__);
                return -1;
        }

        /*进程和共享内存脱离*/
        if(shmdt(pshm_addr) == -1)
        {
                printf("%s : shmdt failed!\n",__func__);
                return -1;
        }

        /*删除共享内存*/
        if(shmctl(shmid, IPC_RMID, 0) == -1)
        {
                printf("%s : shmctl failed!\n",__func__);
                return -1;
        }
        printf("BYE!\n");

        return 0;
}

 write

#include "sem.h"

int main(void)
{
        int semid, shmid;
        char buf[STR_LEN] = {0};
        void *pshm_addr = NULL;

        shm_t * pshm = NULL;
        int i = 0;

        /*获取信号量标识符*/
        semid = creat_sem( );
        if(semid == -1)
        {
                printf("%s : semid = %d!\n", __func__, semid);
                return -1;
        }

        /*获取共享内存标识符*/
        shmid = shmget(ftok(FTOK_FILE,111), sizeof(shm_t), IPC_CREAT|0666);
        if(shmid == -1)
        {
                printf("%s: shmid = %d!\n", __func__, shmid);
                return -1;
        }

        /*当前进程连接该共享内存段*/
        pshm_addr = shmat(shmid, 0, 0);
        if(pshm_addr == (void *)-1)
        {
                printf("%s : pshm_addr = (void*)-1!\n",__func__);
                return -1;
        }

        pshm = (shm_t*)pshm_addr;
        printf("read process : semid is %d, shmid is %d!\n",semid, shmid);

        for(; ;)
        {
                /*占用信号量,p操作*/
                if(sem_p(semid))
                {
                        printf("%s : sem_p failed !\n",__func__);
                        return -1;
                }

                printf("enter write process!\n");
                printf("enter something, end with end >\n");
                fgets(buf, STR_LEN, stdin);
                pshm->num = i++;
                strcpy(pshm->buf, buf);
                printf("leave write process!\n\n");

                /*释放信号量,v操作*/
                if(sem_v(semid))
                {
                        printf("%s : sem_v failed!\n",__func__);
                        return -1;
                }

                if(!strncmp(pshm->buf , "end", 3))
                        break;
        }


        /*进程和共享内存脱离*/
        if(shmdt(pshm_addr) == -1)
        {
                printf("%s : shmdt is failed!\n",__func__);
                return -1;

        }

        printf(" Good Bye! \n");
        return 0;
}

 

共享内存和信号量

标签:blog   io   ar   for   sp   数据   div   on   log   

原文地址:http://www.cnblogs.com/kangbry/p/4060788.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!