go - 如何与 Golang 共享内存?

标签 go ipc

<分区>

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

最佳答案

在围棋的世界里,不要通过共享内存来交流;通过通信共享内存。如果你真的想尝试一下,你可以用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

关于go - 如何与 Golang 共享内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30705397/

相关文章:

C 程序守护进程使用 100% 的 cpu 使用率

php - linux下C和PHP进程间通信有什么好的方法

go - 使用 Go 查询 sqlite 数据库,但没有任何行被扫描到变量中

xml - 戈朗 : write marshal xml to file

go - "go generate"多行命令

C、是否可以阻塞进程直到再次打开管道?

electron - 使用IPC层和contextBridge将数据发送到Electron中的渲染器

ruby-on-rails - 如何通过Rails实现基于websocket的推送服务?

go - HyperLedger fabric 链码未更新

json - 在golang中让节点树转json?