【发布时间】:2014-04-11 03:10:43
【问题描述】:
我正在研究共享内存,现在我正在编写一个使用 system v 共享内存的程序。这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <fcntl.h>
#define PG_SIZE sysconf(_SC_PAGESIZE)
#define PROJ_ID 1
#define SHM_FILE "/dev/shm/myshm"
void executeChild( void );
void executeParent( void );
int main ( int argc, char *argv[] )
{
unlink(SHM_FILE);
int fd = creat(SHM_FILE, S_IRWXU );
if( fd == -1 ){
perror("Segment memory file creation failed");
exit(1);
}
int pid = fork();
if( pid < 0){
perror("Fork failed\n");
return EXIT_FAILURE;
}
if( pid ){
executeParent();
printf("Parent waiting...\n");
int status = 0;
wait(&status); //wait for child process
printf("Parent done\n");
}else{
executeChild();
}
close( fd );
return EXIT_SUCCESS;
}
void executeChild( void )
{
printf("Child running\n");
sleep(15);
}
void executeParent( void )
{
printf("Parent running\n");
key_t token = ftok(SHM_FILE, PROJ_ID);
if( token == -1 ){
perror("Token creation failed");
exit(1);
}
int segment = shmget( token, PG_SIZE, IPC_CREAT | IPC_EXCL | S_IRWXU);
if ( segment == -1 ){
perror("Segment creation failed");
exit(1);
}
void * shm_ptr = shmat(segment, NULL, 0);
if( shm_ptr == (void *)(-1) ){
perror("Segment attachament failed");
exit(1);
}
printf("Shared memory ( %d ) attached\n", segment);
struct shmid_ds shm_info;
if( shmctl(segment, IPC_STAT, &shm_info) == -1 ){
perror("shmctl failed");
exit(1);
}
printf("Segment size = %zu\n", shm_info.shm_segsz);
printf("Writing...\n");
const char * test = "teste";
memcpy(shm_ptr, test, strlen(teste));
}
创建共享内存的文件。我可以在 /dev/shm 上看到它,而 icps commando 也显示了它。但是我的共享内存段的文件大小并没有增加。所以我认为 memcpy 没有像我预期的那样正常工作。为什么?
【问题讨论】:
-
PG_SIZE 是共享内存段的大小。它不会自行改变。而且你应该小心不要超过它。
-
好的,谢谢您的建议。但我没有超过 PG_SIZE。我在一个 40mg 的共享内存段上测试了写入,也没有工作。
-
顺便问一下,你有没有尝试过其他的共享内存方法? /dev/shm 通常是“shm_open()”用来放置它的对象的地方,并且不应该由用户直接修改,所以你应该首先尝试使用它(shm_open/mmap)。或者,尝试在其他地方创建您的基础文件,但即便如此您可能不需要 SYSV shmem:您可以只使用 MAP_SHARED 标志映射该文件。
标签: c linux shared-memory