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本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报