Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 写入SystemV共享内存段_C_Linux_Shared Memory - Fatal编程技术网

C 写入SystemV共享内存段

C 写入SystemV共享内存段,c,linux,shared-memory,C,Linux,Shared Memory,我正在研究共享内存,现在我正在编写一个使用SystemV共享内存的程序。这是我的代码: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <sys/shm.h> #include <sys/ipc.h>

我正在研究共享内存,现在我正在编写一个使用SystemV共享内存的程序。这是我的代码:

#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));
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义PG_SIZE sysconf(_SC_PAGESIZE)
#定义项目ID 1
#定义SHM_文件“/dev/SHM/myshm”
作废执行文件(作废);
作废执行租金(作废);
int main(int argc,char*argv[])
{
取消链接(SHM_文件);
int fd=creat(SHM_文件,S_IRWXU);
如果(fd==-1){
perror(“段内存文件创建失败”);
出口(1);
}
int-pid=fork();
if(pid<0){
perror(“Fork失败\n”);
返回退出失败;
}
如果(pid){
executeParent();
printf(“家长等待…\n”);
int status=0;
等待(&状态);//等待子进程
printf(“父项完成\n”);
}否则{
executeChild();
}
关闭(fd);
返回退出成功;
}               
void executeChild(void)
{
printf(“子运行\n”);
睡眠(15);
}    
作废执行租金(作废)
{
printf(“父运行\n”);
密钥令牌=ftok(SHM文件,项目ID);
如果(令牌==-1){
perror(“令牌创建失败”);
出口(1);
}
int段=shmget(令牌、PG大小、IPC创建| IPC不包括| S IRWXU);
如果(段==-1){
perror(“段创建失败”);
出口(1);
}
void*shm_ptr=shmat(段,空,0);
如果(shm_ptr==(void*)(-1)){
perror(“段连接失败”);
出口(1);
}
printf(“共享内存(%d)已连接\n”,段);
结构shmid_ds shm_info;
如果(shmctl(段、IPC统计和shm信息)=-1){
perror(“shmctl失败”);
出口(1);
}
printf(“段大小=%zu\n”,shm_info.shm_segsz);
printf(“写入…\n”);
const char*test=“teste”;
memcpy(shm_ptr,test,strlen(teste));
}

创建共享内存的文件。我可以在/dev/shm上看到它,icps commando也会显示它。但是我的共享内存段的文件大小没有增加。所以我认为memcpy没有像我预期的那样正常工作。为什么?

最后,我明白了共享内存是如何工作的。。。特别感谢蒂亚戈·科洛克。 传递给ftok的文件不会更改其大小。它的存在只是为了生成进程间通信中使用的唯一密钥…:)

这是我的源代码,其中父进程向子进程写入一条简单消息:


PG_SIZE是共享内存段的大小。它不会自行改变。你应该小心不要超过它。是的,谢谢你的建议。但我没有超过PG_的尺寸。我在一个40mg的共享内存段上测试了write,但也不起作用。顺便问一下,你有没有尝试过其他的共享内存方法/dev/shm通常是“shm_open()”用来放置其对象的位置,不应该由用户直接修改,所以您应该先尝试使用它(shm_open/mmap)。或者,尝试在其他地方创建基础文件,但即使这样,您也可能不需要SYSV shmem:您可以使用MAP_SHARED标志来映射该文件。