douying4203 2015-06-08 09:22
浏览 153
已采纳

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

How does golang share or read other processes shared memory? I've checked some information, but did not find relevant information. Can anyone give me an example?

  • 写回答

2条回答 默认 最新

  • duanmao1919 2015-06-08 10:02
    关注

    In the world of go, don't communicate by sharing memory; share memory by communicating. If you really want to have a try, you can call the C API with cgo:

    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)
    }
    

    run the writer, then the reader by go run filename. The code is from here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 idea自动补全键位冲突
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 定制ai直播实时换脸软件
  • ¥100 栈回溯相关,模块加载后KiExceptionDispatch无法正常回溯了
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页