【linux】系统编程-4-共享内存

时间:2021-01-04 11:19:12   收藏:0   阅读:0


前言

6. 共享内存

6.1 概念

6.2 操作函数

6.2.1 shmget()

6.2.2 shmat()

6.2.3 shmdt()

6.2.4 shmctl()

6.3 例子

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "sem.h"

int main()
{
    int running = 1;
    void *shm = NULL; // 共享内存首地址(*本进程的虚拟地址*)
    struct shared_use_st *shared = NULL;
    char buffer[BUFSIZ + 1];
    int shmid; //共享内存标识符
    int semid; //信号量标识符

    //创建共享内存    
    shmid = shmget((key_t)1234, 4096, 0644 | IPC_CREAT);    
    if(shmid == -1)
    {
        fprintf(stderr, "shmget failed\n");
        exit(EXIT_FAILURE);
    }
    //将共享内存连接到当前进程的地址空间    
    shm = shmat(shmid, (void*)0, 0);    
    if(shm == (void*)-1)
    {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("Memory attached at %p\n", shm);

    /* 打开信号量,不存在则创建一个信号量 */
    semid = semget((key_t)6666, 1, 0666|IPC_CREAT);
    if(semid == -1)
    {
        printf("sem open fail\n");
        exit(EXIT_FAILURE);
    }

    while(running)//向共享内存中写数据
    {
        //向共享内存中写入数据
        printf("Enter some text: ");        
        fgets(buffer, BUFSIZ, stdin); // 阻塞等待标准输入
        strncpy(shm, buffer, 4096);

        sem_v(semid);/* 释放信号量 */

        //输入了end,退出循环(程序)
        if(strncmp(buffer, "end", 3) == 0)
            running = 0;
    }

    //把共享内存从当前进程中分离    
    if(shmdt(shm) == -1)    
    {
        fprintf(stderr, "shmdt failed\n");
        exit(EXIT_FAILURE);
    }
    sleep(2);
    exit(EXIT_SUCCESS);
}
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "sem.h"

int main(void)
{
    int running = 1;//程序运行标志
    char *shm = NULL;// 共享内存首地址(*本进程的虚拟地址*)
    int shmid;// 共享内存标识符
    int semid;// 信号量标识符

    //创建共享内存    
    shmid = shmget((key_t)1234, 4096, 0666 | IPC_CREAT);    
    if(shmid == -1)
    {
        fprintf(stderr, "shmget failed\n");
        exit(EXIT_FAILURE);
    }

    //将共享内存连接到当前进程的地址空间    
    shm = shmat(shmid, 0, 0);    
    if(shm == (void*)-1)
    {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("\nMemory attached at %p\n", shm);

    /* 打开信号量,不存在则创建一个信号量 */
    semid = semget((key_t)6666, 1, 0666|IPC_CREAT); /* 创建一个信号量 */    
    if(semid == -1)
    {
        printf("sem open fail\n");
        exit(EXIT_FAILURE);
    }
    init_sem(semid, 0); // 初始化信号量的值为 0

    while(running)// 读取共享内存中的数据
    {
        /** 等待信号量 */
        if(sem_p(semid) == 0)
        {            
            printf("You wrote: %s", shm);            
            sleep(rand() % 3);

            //输入了end,退出循环(程序)
            if(strncmp(shm, "end", 3) == 0)
                running = 0;
        }
    }

    del_sem(semid); /* 删除信号量 */

    //把共享内存从当前进程中分离
    if(shmdt(shm) == -1)
    {
        fprintf(stderr, "shmdt failed\n");
        exit(EXIT_FAILURE);
    }

    //删除共享内存
    if(shmctl(shmid, IPC_RMID, 0) == -1)
    {
        fprintf(stderr, "shmctl(IPC_RMID) failed\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

参考:

* 野火
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!