如何与 Golang 使用共享内存? [关闭]

Posted

技术标签:

【中文标题】如何与 Golang 使用共享内存? [关闭]【英文标题】:how to use share memory with Golang? [closed] 【发布时间】:2015-06-08 09:22:09 【问题描述】:

golang如何共享或读取其他进程共享内存? 我查了一些资料,但没有找到相关资料。谁能举个例子?

【问题讨论】:

也许您正在寻找内存映射文件? 【参考方案1】:

在围棋的世界里,不要通过共享内存来交流;通过通信共享内存。如果你真的想试试,可以用cgo调用C API:

wrapper.c:

#include <stdlib.h> 
#include <string.h>
#include <sys/shm.h>
#include <sys/types.h>

int my_shm_open(char* filename, int open_flag)
    int shm_id;
    key_t key;
    key = ftok(filename, 0x03);
    if(key == -1)
        return -1;
    
    if(open_flag)
        shm_id = shmget(key, 4096, IPC_CREAT|IPC_EXCL|0600);
    else
        shm_id = shmget(key, 0, 0);
    if(shm_id == -1)
        return -1;
    
    return shm_id;


int my_shm_update(int shm_id, char* content)
    char* addr;
    addr = (char*)shmat(shm_id, NULL, 0);
    if(addr == (char*)-1)
        return -1;
    
    if(strlen(content) > 4095)
        return -1;
    strcpy(addr, content);
    shmdt(addr);
    return 0;


int my_shm_close(int shm_id)
    shmctl(shm_id, IPC_RMID, NULL);
    return 0;


char* my_shm_read(char* filename)
    int shm_id;
    char* addr;
    char* s;
    shm_id = my_shm_open(filename, 0);
    if(shm_id == -1)
        return NULL;
    addr = (char*)shmat(shm_id, NULL, 0);
    if(addr == (char*)-1)
        return NULL;
    
    s = (char*)malloc(strlen(addr) + 1);
    strcpy(s, addr);
    shmdt(addr);
    return s;

reader.go

package main

// #include <stdlib.h>
// #include "wrapper.c"
import "C"
import "unsafe"
import "fmt"

func read(filename string) string 
    f := C.CString(filename)
    defer C.free(unsafe.Pointer(f))
    s := C.my_shm_read(f)
    defer C.free(unsafe.Pointer(s))
    return C.GoString(s)


func main() 
    fmt.Println(read("/tmp"))

writter.go:

package main

// #include <stdlib.h>
// #include "wrapper.c"
import "C"
import "unsafe"

import (
    "log"
    "time"
)

type errorString struct 
    s string


func (e *errorString) Error() string 
    return e.s


func open(file string) (int, error) 
    f := C.CString(file)
    defer C.free(unsafe.Pointer(f))
    r := int(C.my_shm_open(f, C.int(1)))
    if r == -1 
        return 0, &errorString"error"
    
    return r, nil


func update(shm_id int, content string) error 
    c := C.CString(content)
    defer C.free(unsafe.Pointer(c))
    r := int(C.my_shm_update(C.int(shm_id), c))
    if r == -1 
        return &errorString"update error"
    
    return nil


func close(shm_id int) error 
    C.my_shm_close(C.int(shm_id))
    return nil


func main() 
    id, err := open("/tmp")
    if err != nil 
        log.Fatal(err)
    
    defer close(id)
    err = update(id, "hello world")
    if err != nil 
        log.Fatal(err)
    
    time.Sleep(1e9 * 100)

运行作者,然后运行读者go run filename。 代码来自here

【讨论】:

【参考方案2】:

golang:它是一种编程语言,所以它与操作系统级别的东西的共享内存无关。不是说golang不使用共享内存,但这不是它需要定义的。 posix使用共享内存,可以使用syscall包,里面包含很多系统调用,只要引用c系统调用接口就行了。

【讨论】:

以上是关于如何与 Golang 使用共享内存? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何理解“不要通过共享内存来通信,而应该通过通信来共享内存”?

与linux和windows c++兼容的共享内存库[关闭]

golang channel本质——共享内存

以通信方式共享内存,不要以共享内存方式通信

仅使用本机 C++ 操作为多个进程创建共享内存? [关闭]

gpu共享内存几乎不被使用,共享gpu内存用不了