简体   繁体   English

共享内存包含指针

[英]shared memory contain pointer

http://man7.org/training/download/posix_shm_slides.pdf page 22-30 describe : http://man7.org/training/download/posix_shm_slides.pdf第22-30页描述:

Suppose we have situation at right baseaddr is return value from mmap() Want to store pointer to target in *p 假设我们在正确的baseaddr处的情况是mmap()的返回值要在* p中存储指向目标的指针

Wrong way *p = target 错误的方式* p =目标

Correct method (relative offset) : *p = target - baseaddr ; 正确的方法(相对偏移量):* p = target-baseaddr;

To dereference pointer : target = baseaddr + *p ; 要取消引用指针:target = baseaddr + * p;

According to this , I have the following source implement : 据此,我有以下源码工具:

shmem1.cpp : shmem1.cpp:

struct datafeed
{
    int seqno ;
    int val1 ;
    char *ptr ;
    int val2 ;
} ;

static datafeed  *conf;
#define STATE_FILE "/datafeed.shared"

#define ARRAYSIZE 50

int main(int argc, char* argv[])
{
    int shm_fd;
    if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_EXCL | O_RDWR),
                       (S_IREAD | S_IWRITE))) > 0 ) {
        ; /* We are the first instance */
    }
    else if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_RDWR),
                    (S_IREAD | S_IWRITE))) < 0)
    {
        printf("Could not create shm object. %s\n", strerror(errno));
        exit( 0 ) ;
    }
    int iTotalByte = sizeof(datafeed)*ARRAYSIZE ;
    ftruncate(shm_fd, iTotalByte );
    conf =  (datafeed*) mmap(0, iTotalByte ,
            (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0) ;
    if(conf  == MAP_FAILED)
    {
        printf(" mmap error ....\n")  ;
        exit( 0 ) ;
    }
    (conf+0)->seqno++ ;
    (conf+0)->val1++ ;
    (conf+0)->val2 = (conf+0)->val2 + 2  ;
    char *p = new char(128) ;
    strcpy(p,"hello world") ;
    (conf+0)->ptr = (char *)((char *)p - (char *)conf)  ;
}

and shmem2.cpp 和shmem2.cpp

int main(int argc, char* argv[])
{
    int shm_fd;
    if((shm_fd = shm_open(STATE_FILE, (O_RDWR),
                (S_IREAD | S_IWRITE))) < 0) {
        printf("Could not create shm object. %s\n", strerror(errno));
        return errno;
    }
    int iTotalByte = sizeof(datafeed)*ARRAYSIZE ;
    ftruncate(shm_fd, iTotalByte );
    conf =  (datafeed *)mmap(0, iTotalByte , 
            (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0) ;
    if(conf  == MAP_FAILED)
    {
        printf("error in mmap \n") ;
        exit(0) ;
    }
    int seqno = (conf+0)->seqno ;
    int val1 = (conf+0)->val1 ;
    int val2 = (conf+0)->val2 ;
    printf("(%d)(%d)(%d)\n",seqno,val1,val2) ;
    //char *p = (char *) ( (char *)conf + (conf+0)->ptr ) ;
    char *p = (char *) ( (char *)conf + *((conf+0)->ptr) ) ;
    printf("(%s)\n",p) ;
}

compiled on g++ 4.8.2 : 在g ++ 4.8.2上编译:

g++ --std=c++11 shmem1.cpp -lrt -o shmem1.exe
g++ --std=c++11 shmem2.cpp -lrt -o shmem2.exe

run shmem1.exe 2 times look fine to me , then shmem2.exe segment fault : 运行shmem1.exe 2次对我来说很好,然后shmem2.exe段错误:

(2)(2)(4)
Segmentation fault

I really don't get offset meaning in this description , What should I modify the source to get the correct "hello world" ?! 在此描述中,我确实没有得到偏移的含义,该如何修改源代码才能获得正确的“ hello world”?

Edit : 编辑:

http://accu.org/index.php/journals/376 http://accu.org/index.php/journals/376

excellent webpage to refer to . 优秀网页参考。

char *p = new char(128) ;
(conf+0)->ptr = (char *)((char *)p - (char *)conf)  ;

With this you are creating pointer p and storing its value (relative or absolute, does not matter) in shared memory. 这样,您将创建指针p并将其值(相对或绝对,无关紧要)存储在共享内存中。

But when you read it from another process, the address of p may not be valid in that process, as its from another process. 但是,当您从另一个进程中读取它时, p的地址可能在该进程中无效,就像在另一个进程中一样。 So its like accessing unallocated memory address. 因此,就像访问未分配的内存地址一样。 And this would cause segfault. 这会导致段错误。

One thing that is not clear in the document you referred is that, the address that you want to store in shared memory should also reside in same shared memory. 您引用的文档中尚不清楚的一件事是,您要存储在共享内存中的地址也应该驻留在同一共享内存中。 You cannot store address (again absolute or relative) in shared memory and access it from another process safely. 您不能将地址(再次使用绝对地址或相对地址)存储在共享内存中,并且无法从另一个进程安全地访问它。

So you need to extend the shared memory you created to store p containing string "hello world" . 因此,您需要扩展创建的共享内存,以存储包含字符串"hello world" p In another word, instead new() or malloc() you should get appropriate free address from shared memory for p . 换句话说,应该从共享内存中为p获得new()malloc()适当空闲地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM