[英]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.