关于共享内存的一个题目(未完)

一万个计划,不如一个行动,从今天开始重新写博客,立志每周至少写一篇,并且要不断坚持下去。

今天比较闲,因为明天要负责别的项目,所以切换期整好可以偷下懒。同事下午给我了一个题目让我帮忙做下,后来才知道他在帮一个国外的妹纸,细节就不多讲了:-)……题目如下,我是用中文回答的:

Youare to develop and answer the following questions:

  1. Aprogram which will create a shared memory region.

    1. Ifthat region exists, remove the region and try again.

    2. Thepointer type to the region is up to your discretion.

    3. TheSHMID is based on a key from a local text file in your workingdirectory.

    4. Choosethe size of the region to be more than 1 (one) memory page and nota page size multiple (ex size=125445).

  2. Yourprogram will print out the key id from the SHM region in HEX format.

  3. Yourprogram will also capture a signal SIGSEGV.

    1. UponSIGSEGV, your program will print out the number of bytes written tothe region.

  4. Yourprogram will write to the shared memory region until a SIGSEGVoccurs.

    1. Writingany random number or a constant of your data type from offset 0until SIGSEGV

    2. Thenreset the counter do 4.a again.

  5. Yourprogram will loop 5 times (step 4 five times).


Questions:

  1. Dida SIGSEGV signal occur and what was the number of bytes written tothe region before the signal was captured?

如果只写一次,且你的数据类型的大小不超过共享内存大小,不会发生sigsegv

如果连续写共享内存,假设你设置的共享内存有125445个字节,每页有4096个字节,则共享内存会有31页,即126976个字节,假设每次写4个字节,则会写入126976个字节,然后再继续写就有可能会产生sigsegv

  1. Whydid the SIGSEGV occur or what analysis do you have on why it did notoccur.

内存越界

  1. Isthere a difference between the number of bytes written than yourrequested size during creation of the SHM region.

                thenumber of bytes written:所写内存大小

                yourrequested size duringcreation:共享内存最大大小为页整数倍,即4096的整数倍,如果shmget的第二个参数不为4096的整数倍,操作系统会给该共享内存进行4096的对齐

                所写的内存大小需要在所创建内存大小范围之内,否则会出现内存越界,会抛出段错误

  1. Couldyou complete item 5 of the program? Please explain why or why not.

                这个程序不能循环执行,因为程序产生了段错误之后,便会进入信号处理函数处理,处理完之后继续回到出错的地方,该错误会继续产生,即会不断抛出SIGSEGV信号,而无法完成剩下的4次循环

---------------------------------------------------------------------------------------

回过头来看这个题目,貌似这个题目考察以下几个内容

1.shmget函数中第二个参数不论你怎么设置,操作系统会帮你进行页对齐

2.内存越界会产生段错误(关于题干的第四点依然不是很懂,不明白是不断顺序写还是只写一个随机数或常量)

3.SIGSEGV信号的捕获之后,程序的行为如何


今天做这个题目花了不少时间,主要是对共享内存的使用不熟,做题的同时顺便也补补课。在解决第三个问题的时候,发现网上有人用siglongjmp的方式从信号处理函数跳回产生SIGSEGV的地方,然后通过之前保存的sigsetjmp恢复出错之前的环境,想用这样的方式循环五次,但最后还是失败告终,具体为什么会这样还没有弄清楚,代码先保存起来,在这里做个记录,以后有时间再找出具体的原因把。关于这道题的程序代码如下:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <setjmp.h>

const char *path = "/tmp";
int memsize = 4097;
int count = 0;
unsigned int *tmpbuf = 0;
unsigned int *buf = 0;
sigjmp_buf env;

void recvSignal(int sig)  
{  
    printf("received segment fault,  count = %d !!!\n", count);  
    count = 0;
    siglongjmp(env, 1);
}  

int main()
{
    //signal(SIGSEGV, recvSignal);
    
    key_t key = ftok(path, 'a');
    if (key < 0)
    {
        fprintf(stderr, "ftok err: %s\n", strerror(errno));
        return -1;
    }

    int shmid = shmget(key, memsize, 0666 | IPC_CREAT | IPC_EXCL);
    if (shmid < 0)
    {
        // delete the old 
        shmid = shmget(key, memsize, 0666 | IPC_CREAT);
        shmctl(shmid, IPC_RMID, NULL);
    }

    // recreate
    shmid = shmget(key, memsize, 0666 | IPC_CREAT | IPC_EXCL);
    if (shmid < 0)
    {
        printf("shmget error: %s\n", strerror(errno));
        return -1;
    }

    printf("SHMID=%d\n", shmid);
    buf = (unsigned int*)shmat(shmid, NULL, 0);

    int i = 0;
    for (; i < 5; i++)
    {
        int r = sigsetjmp(env, 1);

        if (r == 0)
        {
            signal(SIGSEGV, recvSignal);
            tmpbuf = buf;
            printf("tmpbuf=%x, count=%d\n", tmpbuf, count);
            while (1)
            {
                *(tmpbuf++) = 1;
                count += 4;
            }
        }
        else
        {
            printf("jump back");
        }
        sleep(5);
    }

    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值