首页 > 系统相关 >共享内存练习题

共享内存练习题

时间:2024-05-28 13:34:19浏览次数:27  
标签:练习题 共享内存 shmget errno shm include id

设计三个程序,要求三个程序申请一块共享内存,并分别映射到各自进程的地址空间,进程A和进程B对共享内存段中的数据进行修改,然后进程C不断输出共享内存段中的数据,并观察效果,要求实现进程间的互斥,避免竞争。

进程A:

/*******************************************************************
 *
 *	file name:	A.c
 *	author	 :  Dazz
 *	date	 :  2024/05/28
 *	function :  进程A,用于对共享内存中的数据进行修改
 * 	note	 :  None
 *
 *	CopyRight (c)  2024  [email protected]   All Right Reseverd
 *
 * *****************************************************************/

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

char *p;

// 进程A收到信号会对共享内存段中的数据进行修改
void sighandler(int a)
{
    sprintf(p, "Hello,here is processA\n");
}

int main()
{
    // 打开共享内存段,如果不存在则创建,如果存在则打开
    int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
    if (-1 == shm_id)
    {
        // 如果存在则会报错
        fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));

        // 如存在,则打开共享内存段即可
        shm_id = shmget(ftok("..", 76), 512, 0644);
        if (-1 == shm_id)
        {
            // 如打开失败则直接退出程序
            fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
            exit(1);
        }
    }

    // 把共享内存段连接到进程空间
    p = shmat(shm_id, NULL, 0);
    if ((void *)-1 == p)
    {
        // 如连接失败则直接退出程序
        fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
        exit(2);
    }

    // 打印自己的PID
    printf("the PID of processA is %d\n", getpid());

    // 等待接收SIGUSR1的信号
    signal(SIGUSR1, sighandler);

    while (1);

    // 销毁链接得到的虚拟地址
    shmdt(p);

    return 0;
}

进程B:

/*******************************************************************
 *
 *	file name:	B.c
 *	author	 :  Dazz
 *	date	 :  2024/05/28
 *	function :  进程B,用于对共享内存中的数据进行修改
 * 	note	 :  None
 *
 *	CopyRight (c)  2024  [email protected]   All Right Reseverd
 *
 * *****************************************************************/

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

char *p;

// 进程A收到信号会对共享内存段中的数据进行修改
void sighandler(int a)
{
    sprintf(p, "Hi,here is processB\n");
}

int main()
{
    // 打开共享内存段,如果不存在则创建,如果存在则打开
    int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
    if (-1 == shm_id)
    {
        // 如果存在则会报错
        fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));

        // 如存在,则打开共享内存段即可
        shm_id = shmget(ftok("..", 76), 512, 0644);
        if (-1 == shm_id)
        {
            // 如打开失败则直接退出程序
            fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
            exit(1);
        }
    }

    // 把共享内存段连接到进程空间
    p = shmat(shm_id, NULL, 0);
    if ((void *)-1 == p)
    {
        // 如连接失败则直接退出程序
        fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
        exit(2);
    }

    // 等待接收SIGUSR2的信号
    signal(SIGUSR2, sighandler);

    // 打印自己的PID
    printf("the PID of processA is %d\n", getpid());

    while (1);

    // 销毁链接得到的虚拟地址
    shmdt(p);

    return 0;
}

进程C:

/*******************************************************************
 *
 *	file name:	C.c
 *	author	 :  Dazz
 *	date	 :  2024/05/28
 *	function :  进程C,用于读取并输出对共享内存中的数据
 * 	note	 :  None
 *
 *	CopyRight (c)  2024  [email protected]   All Right Reseverd
 *
 * *****************************************************************/

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>

int main()
{
    // 打开共享内存段,如果不存在则创建,如果存在则打开
    int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
    if (-1 == shm_id)
    {
        // 如果存在则会报错
        fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));

        // 如存在,则打开共享内存段即可
        shm_id = shmget(ftok("..", 76), 512, 0644);
        if (-1 == shm_id)
        {
            // 如打开失败则直接退出程序
            fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
            exit(1);
        }
    }

    // 把共享内存段连接到进程空间
    char *p = shmat(shm_id, NULL, 0);
    if ((void *)-1 == p)
    {
        // 如连接失败则直接退出程序
        fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
        exit(2);
    }

    // 手动输入进程A和进程B的pid
    int PidA, PidB;
    printf("please input the PID of processA\n");
    scanf("%d", &PidA);

    printf("please input the PID of processB\n");
    scanf("%d", &PidB);

    while (1)
    {
        // 给进程A发送信号
        kill(PidA, SIGUSR1);

        sleep(2);

        // 输出读到的数据
        printf("%s\n", p);

        // 给进程B发送信号
        kill(PidB, SIGUSR2);

        sleep(2);

        // 输出读到的数据
        printf("%s\n", p);
    }
    // 销毁链接得到的虚拟地址
    shmdt(p);

    return 0;
}

标签:练习题,共享内存,shmget,errno,shm,include,id
From: https://www.cnblogs.com/Dazz24/p/18217784

相关文章

  • 消息队列练习题
    消息队列练习题进程A/**********************************************************************filename:mesqa.c*author:[email protected]*date:2024/5/28*function:接收进程b的信号,读出消......
  • 消息队列练习题
    题目:要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并把进程的PID作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文的内容。进程A的代码://构造用于接收消息......
  • 系统编程练习题----使用消息队列实现两个进程之间的通信
    目录题目思路代码展示进程A进程B结果展示题目要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并写入一段信息作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文......
  • 8. 聚合函数练习题
    【题目】1.where子句可否使用组函数进行过滤?selectmax(salary),min(salary),avg(salary),sum(salary)fromemployeese;2.查询公司员工工资的最大值,最小值,平均值,总和selectmax(salary),min(salary),avg(salary),sum(salary)fromemployeesegroupbyjob_i......
  • 散列(哈希)及其练习题(基础)
    散列导入:有N个数和M个数,如何判断M个数中每个数是否在N中出现?思想:空间换时间创建hashtable,以N个数本身为索引(数组下标)构建boolhashtable输入x的过程中,hashtable[x]=True(若要计算出现次数,换成++)但终归是有局限性!数字只能是整数,还不能太大,等等。散列函数:平房区中法、取余......
  • (十)统计学基础练习题四(50道选择题)
    本文整理了统计学基础知识相关的练习题,共50道,适用于想巩固统计学基础或备考的同学。来源:如荷学数据科学题库(技术专项-统计学一)。序号之前的题请看往期文章。151) 152) 153) 154) 155) 156) 157) 158) 159) 160) 161) 162) 163) 164) ......
  • (九)统计学基础练习题三(50道选择题)
    本文整理了统计学基础知识相关的练习题,共50道,适用于想巩固统计学基础或备考的同学。来源:如荷学数据科学题库(技术专项-统计学一)。序号之前的题请看往期文章。101)102)103)104)105)106)107)108)109)110)111)112)113)114)115)116)117)118)119)120)121)122)......
  • 47.C语言函数练习题整理
    题目来自练习册和牛客网的一些编程题目整理函数都有返回值且只有一个返回值声明类型为void可以返回空值若调用一个函数中没有return语句返回一个不确定的值形参是动态变量实参和形参之间的数据传递方式为实参到形参的单向值传递形参的值发生改变不会影响主调函数中的......
  • 内存映射和共享内存的区别
    内存映射(MemoryMapping)和共享内存(SharedMemory)都是在进程间进行内存共享的机制,但它们在工作原理和使用方式上有一些区别。内存映射(MemoryMapping)工作原理:内存映射是将文件的一部分映射到进程的地址空间中,使得文件内容可以直接被读写,就像操作内存一样。特点:文件内容可以通......
  • JVM非运行时共享内存之直接内存
    直接内存(DirectMemory)并不是虚拟机运行时数据区的一部分。为何存在呢?观察下两图进行对比:有没有似曾相识?!很多架构的设计都基于这种思想,提高性能和效率。NIO的Buffer提供一个可以直接访问系统物......