打印
[嵌入式linux]

【华清远见】linux共享内存实验

[复制链接]
1589|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
shanghaifar|  楼主 | 2013-9-29 15:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    1.实验目的
    通过编写共享内存实验,进一步了解使用共享内存的具体步骤,同时加深对共享内存的理解。在本实验中,采用信号量作为同步机制完善两个进程(“生产者”和“消费者”)之间的通信,其功能类似于4.6节中的实例。在实例中使用信号量同步机制。

    2.实验内容
    该实现要求利用共享内存实现文件的打开和读写操作。

    3.实验步骤
    (1)画出流程图。该实验流程图如图1所示。

图1 实验流程图
    (2)编写代码。下面是共享内存缓冲区的数据结构的定义:
    /* shm_com.h */
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #define SHM_BUFF_SZ 2048
    struct shm_buff
    {
        int pid;
        char buffer[SHM_BUFF_SZ];
    };
    以下是“生产者”程序部分:
    /* sem_com.h 和 sem_com.c 与4.4节示例中的同名程序相同 */
    /* producer.c */
    #include "shm_com.h"
    #include "sem_com.h"
    #include <signal.h>
    int ignore_signal(void)
    { /* 忽略一些信号,以免非法退出程序 */
        signal(SIGINT, SIG_IGN);
        signal(SIGSTOP, SIG_IGN);
        signal(SIGQUIT, SIG_IGN);
        return 0;
    }

    int main()
    {
        void *shared_memory = NULL;
        struct shm_buff *shm_buff_inst;
        char buffer[BUFSIZ];
        int shmid, semid;
        /* 定义信号量,用于实现访问共享内存的进程间的互斥 */
        ignore_signal(); /* 防止程序非正常退出 */
        semid = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); /* 创建一个信号量 */
        init_sem(semid);/* 初始值为1 */

        /* 创建共享内存 */
        shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
        if (shmid == -1)
        {
            perror("shmget failed");
            del_sem(semid);
            exit(1);
        }

        /* 将共享内存地址映射到当前进程地址空间 */
        shared_memory = shmat(shmid, (void*)0, 0);
        if (shared_memory == (void*)-1)
        {
            perror("shmat");
            del_sem(semid);
            exit(1);
        }
        printf("Memory attached at %X\n", (int)shared_memory);
        /* 获得共享内存的映射地址 */
        shm_buff_inst = (struct shared_use_st *)shared_memory;
        do
        {
            sem_p(semid);
            printf("Enter some text to the shared memory(enter 'quit' to exit):");
            /* 向共享内存写入数据 */
            if (fgets(shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL)
            {
                perror("fgets");
                sem_v(semid);
                break;
            }
            shm_buff_inst->pid = getpid();
            sem_v(semid);
        } while(strncmp(shm_buff_inst->buffer, "quit", 4) != 0);

        /* 删除信号量 */
        del_sem(semid);
        /* 删除共享内存到当前进程地址空间中的映射 */
        if (shmdt(shared_memory) == 1)
        {
            perror("shmdt");
            exit(1);
        }
        exit(0);
    }
    以下是“消费者”程序部分:
    /* customer.c */
    #include "shm_com.h"
    #include "sem_com.h"

    int main()
    {
        void *shared_memory = NULL;
        struct shm_buff *shm_buff_inst;
        int shmid, semid;
        /* 获得信号量 */
        semid = semget(ftok(".", 'a'), 1, 0666);
        if (semid == -1)
        {
            perror("Producer is'nt exist");
            exit(1);
        }
        /* 获得共享内存 */
        shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
        if (shmid == -1)
        {
            perror("shmget");
            exit(1);
        }
        /* 将共享内存地址映射到当前进程地址空间 */
        shared_memory = shmat(shmid, (void*)0, 0);
        if (shared_memory == (void*)-1)
        {
            perror("shmat");
            exit(1);
        }
        printf("Memory attached at %X\n", (int)shared_memory);
        /* 获得共享内存的映射地址 */
        shm_buff_inst = (struct shm_buff *)shared_memory;
        do
        {
            sem_p(semid); printf("Shared memory was written by process %d :%s",
            shm_buff_inst->pid, shm_buff_inst->buffer);
            if (strncmp(shm_buff_inst->buffer, "quit", 4) == 0)
            {
                break;
            }
            shm_buff_inst->pid = 0;
            memset(shm_buff_inst->buffer, 0, SHM_BUFF_SZ);
            sem_v(semid);
        } while(1);

        /* 删除共享内存到当前进程地址空间中的映射 */
        if (shmdt(shared_memory) == -1)
        {
            perror("shmdt");
            exit(1);
        }
        /* 删除共享内存 */
        if (shmctl(shmid, IPC_RMID, NULL) == -1)
        {
            perror("shmctl(IPC_RMID)");
            exit(1);
        }
        exit(0);
    }
    4.实验结果
    实验运行结果如下:
    $./producer
    Memory attached at B7F90000
    Enter some text to the shared memory(enter 'quit' to exit):First message
    Enter some text to the shared memory(enter 'quit' to exit):Second message
    Enter some text to the shared memory(enter 'quit' to exit):quit
    $./customer
    Memory attached at B7FAF000
    Shared memory was written by process 3815 :First message
    Shared memory was written by process 3815 :Second message
    Shared memory was written by process 3815 :quit
    本文选自华清远见嵌入式培训教材《从实践中学嵌入式Linux应用程序开发》

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

47

主题

81

帖子

0

粉丝