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

原创 2013年12月02日 21:02:15

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

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

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;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

一个C++的共享内存类

  • 2009-06-11 15:31
  • 61KB
  • 下载

[转]一个很好的Linux共享内存和信号量的例子

本文转自:http://linux.chinaitlab.com/c/825371.html   #include  #include  #include  #include  #include  #...

Linux进程间通信(IPC)编程实践(十一)System V信号量---实现一个先进先出的共享内存shmfifo

使用消息队列即可实现消息的先进先出(FIFO), 但是使用共享内存实现消息的先进先出则更加快速;    我们首先完成C语言版本的shmfifo(基于过程调用), 然后在此基础上实现C++版本的S...

Linux 创建共享内存 从一个程序写一个程序读

读取c 文件图右 #include #include #include #include #include "shmdata.h" int main() { int runing=1; ...

共享内存实现大规模点积

  • 2014-09-22 15:48
  • 10.86MB
  • 下载

共享内存的属性结构体

  • 2015-06-09 22:53
  • 938B
  • 下载

一类凸包题目(未完)

注:《黑书》P392中有讲:对于通常求的凸包,输出的凸包是包括所有可能的共线点还是不包括任何共线点(即只有极点)这是取决于题目的题目要求的。在下面的程序中都会将去共线点的代码加上,视题目删除。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)