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

报告相同问题?

悬赏问题

  • ¥50 关于#html5#的问题:H5页面用户手机返回的时候跳转到指定页面例如(语言-javascript)
  • ¥15 无法使用此凭据登录,因为你的域不可用,如何解决?(标签-Windows)
  • ¥15 yolov9的训练时间
  • ¥15 二叉树遍历没有报错但无法正常运行
  • ¥15 在linux系统下vscode运行robocup3d上场球员报错
  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式
  • ¥15 在使用abaqus软件中,继承到assembly里的surfaces怎么使用python批量调动