IPC机制---共享内存编程

41 篇文章 2 订阅
#include <stdio.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"

#define MAX_STRING  5000

typedef struct {
    int semID;
    int counter;
    char string[MAX_STRING+1];
} MY_BLOCK_T;
int main(int argc, char *argv[])
{
    int shmid, ret, i;
    MY_BLOCK_T *block;
    struct sembuf sb;
    char user;

    /* Make sure there's a command */
    if(argc >= 2)
    {
        /* Create the shared memory segment and init it with the semaphore */
        if(!strncmp(argv[1], "create", 6))
        {
            /* Create the shared memory segment and semaphore */
            printf("Creating the shared memory segment\n");

            /* Create the shared memory segment */
            shmid = shmget(MY_SHM_ID, sizeof(MY_BLOCK_T), (IPC_CREAT | 0666));

            /* Attach to the segment */
            block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);

            /* Initialize our write pointer */
            block->counter = 0;

            /* Create the semaphore */
            block->semID = semget(MY_SEM_ID, 1, (IPC_CREAT | 0666));

            /* Increment the semaphore */
            sb.sem_num = 0;
            sb.sem_op = 1;
            sb.sem_flg = 0;
            semop(block->semID, &sb, 1);

            /* Now detach from the segment */
            shmdt((void *)block);
        }
 else if(!strncmp(argv[1], "use", 3))
        {
            /* Use the segment */

            /* Must specify also a letter (to write to the buffer) */
            if(argc < 3)
                exit(-1);

            user = (char)argv[2][0];

            /* Grab the shared memory segment */
            shmid = shmget(MY_SHM_ID, 0, 0);

            /* Attach to it */
            block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);

            for(i = 0; i < 2500;  i++)
            {
                /* Give up the CPU temporarily */
                sleep(0);

                /* Grab the semaphore */
                sb.sem_num = 0;
                sb.sem_op = -1;
                sb.sem_flg = 0;
                if(semop(block->semID, &sb, 1) != -1)
                {
                    /* Write our letter to the segment buffer(only we have the semaphore). This is our critical section */
                    block->string[block->counter++] = user;

                    /* Release the semaphore */
                    sb.sem_num = 0;
                    sb.sem_op = 1;
                    sb.sem_flg = 0;
                    if(semop(block->semID, &sb, 1) == -1)
                    {
                        printf("Failed to release the semaphore\n");
                    }
                }
                else
                {
                    printf("Failed to acquire the semaphore\n");
                }
            }
            /* We're done, unmap the shared memory segment. */
ret = shmdt((void *)block);
        }
        else if(!strncmp(argv[1], "read", 6))
        {
            /* Here, we'll read the buffer in the shared segment */
            shmid = shmget(MY_SHM_ID, 0, 0);

            if(shmid != -1)
            {
                block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);

                /* Terminate the buffer */
                block->string[block->counter+1] = 0;

                printf("%s\n", block->string);

                ret = shmdt((void *)block);
            }
            else
            {
                printf("Unable to read segment.\n");
            }
        }
else if(!strncmp(argv[1], "remove", 6))
        {
            shmid = shmget(MY_SHM_ID, 0, 0);

            if(shmid >= 0)
            {
                block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);

                /* Remove the semaphore */
                ret = semctl(block->semID, 0, IPC_RMID);

                /* Remove the shared segment */
                ret = shmctl(shmid, IPC_RMID, 0);

                if(ret == 0)
                {
                    printf("Successfully removed the segment.\n");
                }
            }
        }
        else
        {
            printf("Unknown command %s\n", argv[1]);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值