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

huangapple go评论82阅读模式
英文:

how to use share memory with Golang?

问题

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?

答案1

得分: 1

在Go语言世界中,不要通过共享内存来进行通信;而是通过通信来共享内存。如果你真的想尝试一下,你可以使用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"))
}

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

运行writer,然后通过go run filename运行reader。代码来源于这里

英文:

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 &lt;stdlib.h&gt; 
#include &lt;string.h&gt;
#include &lt;sys/shm.h&gt;
#include &lt;sys/types.h&gt;
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) &gt; 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 &lt;stdlib.h&gt;
// #include &quot;wrapper.c&quot;
import &quot;C&quot;
import &quot;unsafe&quot;
import &quot;fmt&quot;
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(&quot;/tmp&quot;))
}

writter.go:

package main
// #include &lt;stdlib.h&gt;
// #include &quot;wrapper.c&quot;
import &quot;C&quot;
import &quot;unsafe&quot;
import (
&quot;log&quot;
&quot;time&quot;
)
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, &amp;errorString{&quot;error&quot;}
}
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 &amp;errorString{&quot;update error&quot;}
}
return nil
}
func close(shm_id int) error {
C.my_shm_close(C.int(shm_id))
return nil
}
func main() {
id, err := open(&quot;/tmp&quot;)
if err != nil {
log.Fatal(err)
}
defer close(id)
err = update(id, &quot;hello world&quot;)
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

答案2

得分: -7

golang:它是一种编程语言,因此与操作系统级别的共享内存无关。并不是说golang不使用共享内存,但这不是它需要定义的。Posix使用共享内存,你可以使用syscall包,其中包含许多系统调用,只要参考C系统调用接口即可。

英文:

golang: It is a programming language, so it does not relate to the shared memory that the operating system level things. Not to say golang not use shared memory, but this is not it need to be defined. Posix use shared memory, you can use syscall package, which contains a lot of system calls, as long as the reference c system call interface on the line.

huangapple
  • 本文由 发表于 2015年6月8日 17:22:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/30705397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定