将大于页面大小的数据写入共享内存
Writing data bigger than page size into shared memory
我的处理器的页面大小为 4096。我需要将数据写入共享内存,该数据的大小为 7168 (7 KB)。
我使用了 ftruncate 并分配了 8192 (2*page_size) 以便有足够的内存。
shmem_fd = shm_open( TRIAL_SHMEM_FILE, O_RDWR, S_IRUSR | S_IWUSR);
if( shmem_fd == -1 )
{
printf("Create_shmem, open failed:%s",strerror( errno));PASLOG return false;
}
if( ftruncate( shmem_fd, 8192) == -1 )
{
printf("Create_shmem, ftruncate failed:%s",strerror( errno));PASLOG return false;
}
我写的结构如下。 [767*10] 字节小于 [2*page_size]。但是下面的代码会导致分段错误。
如果我尝试写入 [1-page_size] 内的 [767*5],则不会发生崩溃。我无法知道坠机的真正原因。是否有其他方法可以继续?
// data to be written into shared memory
list_data item[10]; // struct size is 767 bytes
for (uiCounter=DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memset(&item[uiCounter], 0, sizeof(list_data));
}
list_data* list_shmem;
list_shmem = (list_data *) mmap(NULL, sizeof(list_data) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, shmem_fd, 0 );
if(list_shmem == MAP_FAILED)
{
printf("mmap failsed: %s", strerror(errno));
return false;
}
// write to shared mem
for (uiCounter = DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memcpy ( list_shmem, &item[uiCounter], sizeof(person) );
++list_shmem;
}
munmap(list_shmem, sizeof(list_data) * 10);
您的代码有几个问题:
您将错误的地址传递给 munmap
in:
list_data* list_shmem;
list_shmem = (list_data *) mmap(...);
for (uiCounter = DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memcpy ( list_shmem, &item[uiCounter], sizeof(person) );
++list_shmem; // <---- invalidates list_shmem original value
}
munmap(list_shmem, sizeof(list_data) * 10);
您在 memcpy
中指定了错误的尺寸:
memcpy ( list_shmem, &item[uiCounter], sizeof(person) );
修复方法是:
memcpy ( list_shmem, &item[uiCounter], sizeof(item[uiCounter]) );
解决这两个问题的一个方法是使用标准算法 std::copy
而不是手动编码的循环:
std::copy(item + DEFAULT_VALUE_ZERO, item + 10, list_shmem);
奖励积分:
list_data item[10]; // struct size is 767 bytes
for (uiCounter=DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memset(&item[uiCounter], 0, sizeof(list_data));
}
等同于:
list_data item[10] = {};
我的处理器的页面大小为 4096。我需要将数据写入共享内存,该数据的大小为 7168 (7 KB)。 我使用了 ftruncate 并分配了 8192 (2*page_size) 以便有足够的内存。
shmem_fd = shm_open( TRIAL_SHMEM_FILE, O_RDWR, S_IRUSR | S_IWUSR);
if( shmem_fd == -1 )
{
printf("Create_shmem, open failed:%s",strerror( errno));PASLOG return false;
}
if( ftruncate( shmem_fd, 8192) == -1 )
{
printf("Create_shmem, ftruncate failed:%s",strerror( errno));PASLOG return false;
}
我写的结构如下。 [767*10] 字节小于 [2*page_size]。但是下面的代码会导致分段错误。 如果我尝试写入 [1-page_size] 内的 [767*5],则不会发生崩溃。我无法知道坠机的真正原因。是否有其他方法可以继续?
// data to be written into shared memory
list_data item[10]; // struct size is 767 bytes
for (uiCounter=DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memset(&item[uiCounter], 0, sizeof(list_data));
}
list_data* list_shmem;
list_shmem = (list_data *) mmap(NULL, sizeof(list_data) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, shmem_fd, 0 );
if(list_shmem == MAP_FAILED)
{
printf("mmap failsed: %s", strerror(errno));
return false;
}
// write to shared mem
for (uiCounter = DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memcpy ( list_shmem, &item[uiCounter], sizeof(person) );
++list_shmem;
}
munmap(list_shmem, sizeof(list_data) * 10);
您的代码有几个问题:
您将错误的地址传递给
munmap
in:list_data* list_shmem; list_shmem = (list_data *) mmap(...); for (uiCounter = DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter) { memcpy ( list_shmem, &item[uiCounter], sizeof(person) ); ++list_shmem; // <---- invalidates list_shmem original value } munmap(list_shmem, sizeof(list_data) * 10);
您在
memcpy
中指定了错误的尺寸:memcpy ( list_shmem, &item[uiCounter], sizeof(person) );
修复方法是:
memcpy ( list_shmem, &item[uiCounter], sizeof(item[uiCounter]) );
解决这两个问题的一个方法是使用标准算法 std::copy
而不是手动编码的循环:
std::copy(item + DEFAULT_VALUE_ZERO, item + 10, list_shmem);
奖励积分:
list_data item[10]; // struct size is 767 bytes
for (uiCounter=DEFAULT_VALUE_ZERO; uiCounter < 10; ++uiCounter)
{
memset(&item[uiCounter], 0, sizeof(list_data));
}
等同于:
list_data item[10] = {};