簡體   English   中英

共享內存包含指針

[英]shared memory contain pointer

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

假設我們在正確的baseaddr處的情況是mmap()的返回值要在* p中存儲指向目標的指針

錯誤的方式* p =目標

正確的方法(相對偏移量):* p = target-baseaddr;

要取消引用指針:target = baseaddr + * p;

據此,我有以下源碼工具:

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

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

在g ++ 4.8.2上編譯:

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

運行shmem1.exe 2次對我來說很好,然后shmem2.exe段錯誤:

(2)(2)(4)
Segmentation fault

在此描述中,我確實沒有得到偏移的含義,該如何修改源代碼才能獲得正確的“ hello world”?

編輯:

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

優秀網頁參考。

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

這樣,您將創建指針p並將其值(相對或絕對,無關緊要)存儲在共享內存中。

但是,當您從另一個進程中讀取它時, p的地址可能在該進程中無效,就像在另一個進程中一樣。 因此,就像訪問未分配的內存地址一樣。 這會導致段錯誤。

您引用的文檔中尚不清楚的一件事是,您要存儲在共享內存中的地址也應該駐留在同一共享內存中。 您不能將地址(再次使用絕對地址或相對地址)存儲在共享內存中,並且無法從另一個進程安全地訪問它。

因此,您需要擴展創建的共享內存,以存儲包含字符串"hello world" p 換句話說,應該從共享內存中為p獲得new()malloc()適當空閑地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM