为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Golang 中使用共享内存?

如何在 Golang 中使用共享内存?

Go
Helenr 2021-10-11 18:44:05
golang 如何共享或读取其他进程共享内存?我查了一些资料,没有找到相关资料。谁能给我一个例子?
查看完整描述

2 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

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


包装器.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;

}

阅读器


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

}

作家.去:


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。


查看完整回答
反对 回复 2021-10-11
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

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


查看完整回答
反对 回复 2021-10-11
  • 2 回答
  • 0 关注
  • 463 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信