how to use share memory with Golang? [closed] - go

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
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?

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

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.

Related

How to put regexp inside proto struct in golang?

I have a tree-like structure, that has string regexp and I want Go compiled *regexp.Regexp to be part of it as well, in order to run algorithms on the tree. When I marshal and pass it to a different machine I may just recompile it again from the string. What is the correct way to do that, how to force protobuf to store pointers in a structure, that it ideally wont marshal? (the only way that i see is to make uint64 field and cast its value to/from *Regexp)
pseudo-code (because required wanted features seems to be not in the language):
// struct generated by protoc
type ProtoMessage struct {
Data string
Source string
Regexp uint64 // should not be marshalled, should be forcefully omitted from payload when doing proto.Marshal, ideally it should be *regexp.Regexp
Left *ProtoMessage
Right *ProtoMessage
}
func main() {
// sender computer doSend():
mSrc := &ProtoMessage{Data:"its meee!!!", Source: "hello.+world"}
payload, _ := proto.Marshal(m)
//receiver computer: onRecv()
mDst := new(ProtoMessage)
proto.Unmarshal(payload, mDst)
r, _ := regexp.Compile(mDst.Source)
mDst.Regexp = uint64(unsafe.Pointer(r)) // not working btw
TreeMatch = func(tree* ProtoMessage, line string) string {
if *regexp.Regexp(t.Regexp).Match(line) { // not working line
return t.Data
}
if tree.Left == nil {
return ""
}
return TreeMatch(tree.Left, line)
}
assert( TreeMatch(mDst, "hello, world") == "its meee!!!") // panic if condition is false
}
With json marshal i can just pot a pointer to regexp and provide a tag json:"-" in order not to include this field into marshalled structure, and ofc its important feature of marshalling/unmarshalling system to stay efficient (eg use same structure to run algorithms on in, and avoid data copying after unmarshal). How can I do the same with protobuf?
You can't store a pointer in a protobuf, as the recipient is likely a different computer. Even if you could, you'd get a panic as soon as you tried to dereference the pointer. Easiest thing to do would be just pass the RegExp string, then compile again at the destination:
package main
import (
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
)
func main() {
v := structpb.NewStringValue("hello.+world")
b, err := proto.Marshal(v)
if err != nil {
panic(err)
}
fmt.Printf("%q\n", b) // "\x1a\fhello.+world"
}
Note: you can't hack around this with Gob either:
package main
import (
"bytes"
"encoding/gob"
"regexp"
)
func main() {
re := regexp.MustCompile("hello.+world")
buf := new(bytes.Buffer)
if err := gob.NewEncoder(buf).Encode(re); err != nil {
panic(err) // type regexp.Regexp has no exported fields
}
}
Found the solution, you just have to have any pointer inside your struct (no matter if its marshalling or not, you are not using its unmarshalled value on receiver side):
proto declaration:
syntax = "proto3";
package main;
option go_package = ".;main";
message Empty {
}
message ProtoMessage {
string data = 1;
string source = 2;
Empty regexp = 3; // ideally should not be marshalled at all, like `json:"-"` but for protobuf
ProtoMessage left = 4;
ProtoMessage right = 5;
}
testing code:
package main
import (
"regexp"
"testing"
"unsafe"
)
type Empty struct {
//state protoimpl.MessageState
//sizeCache protoimpl.SizeCache
//unknownFields protoimpl.UnknownFields
}
// struct generated by protoc
type ProtoMessage struct {
//state protoimpl.MessageState
//sizeCache protoimpl.SizeCache
//unknownFields protoimpl.UnknownFields
Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"`
Regexp *Empty `protobuf:"bytes,3,opt,name=regexp,proto3" json:"regexp,omitempty"` // ideally should not be marshalled at all, like `json:"-"` but for protobuf
Left *ProtoMessage `protobuf:"bytes,4,opt,name=left,proto3" json:"left,omitempty"`
Right *ProtoMessage `protobuf:"bytes,5,opt,name=right,proto3" json:"right,omitempty"`
}
func (p *ProtoMessage) GetCompiledRegexp() *regexp.Regexp {
return (*regexp.Regexp)(unsafe.Pointer(p.Regexp))
}
func (p *ProtoMessage) SetCompiledRegexp(r *regexp.Regexp) {
p.Regexp = (*Empty)(unsafe.Pointer(r))
}
func TreeMatch(tree *ProtoMessage, line string) string {
if tree.GetCompiledRegexp().Match([]byte(line)) { // not working line
return tree.Data
}
if tree.Left == nil {
return ""
}
return TreeMatch(tree.Left, line)
}
func TestTreeMatch(t *testing.T) {
//happening at receiver side: imagine its proto.Unmarshal(payload, receiverMsg)
receiverMsg := &ProtoMessage{
Data: "its meee!!!",
Source: "hello.+world",
}
r, _ := regexp.Compile(receiverMsg.Source)
receiverMsg.SetCompiledRegexp(r)
if TreeMatch(receiverMsg, "helloworld") != "" {
t.Fatalf("TreeMatch gives non-existing match!")
}
if TreeMatch(receiverMsg, "hello, world") != "its meee!!!" {
t.Fatalf("TreeMatch is not working!")
}
}
type ProtoMessageDirect struct {
Data string
Source string
Regexp *regexp.Regexp
Left *ProtoMessageDirect
Right *ProtoMessageDirect
}
func (p *ProtoMessageDirect) GetCompiledRegexp() *regexp.Regexp {
return p.Regexp
}
func (p *ProtoMessageDirect) SetCompiledRegexp(r *regexp.Regexp) {
p.Regexp = r
}
func TreeMatchDirect(tree *ProtoMessageDirect, line string) string {
if tree.GetCompiledRegexp().Match([]byte(line)) { // not working line
return tree.Data
}
if tree.Left == nil {
return ""
}
return TreeMatchDirect(tree.Left, line)
}
func BenchmarkRegexpCast(b *testing.B) {
receiverMsg := &ProtoMessage{
Data: "its meee!!!",
Source: "hello.+world",
}
r, _ := regexp.Compile(receiverMsg.Source)
receiverMsg.SetCompiledRegexp(r)
b.ResetTimer()
for i := 0; i < b.N; i++ {
TreeMatch(receiverMsg, "hello, world")
}
}
func BenchmarkRegexpDirect(b *testing.B) {
receiverMsg := &ProtoMessageDirect{
Data: "its meee!!!",
Source: "hello.+world",
}
r, _ := regexp.Compile(receiverMsg.Source)
receiverMsg.SetCompiledRegexp(r)
b.ResetTimer()
for i := 0; i < b.N; i++ {
TreeMatchDirect(receiverMsg, "hello, world")
}
}
TestTreeMatch is passing and Benchmarks shows that such a cast does not create any meaningful difference:
BenchmarkRegexpCast-20 2741786 376.7 ns/op 16 B/op 1 allocs/op
BenchmarkRegexpDirect-20 3075280 377.0 ns/op 16 B/op 1 allocs/op
PASS

copy buffer into type struct based on data

My requirement is to convert byte stream into my structure type, which has predefined data lengths.
Below sample, I could convert byte into "Test" object and read data(func buffertoStruct demonstrates that),
but the problem is
I need to cast into data types based on the string or int lengths. which is not happening now.
I have lots of different structures like "type Test" and each struct will have a good amount of data variables. So copying bytes into struct Test variables based on sizes one by one doesn't work.
WHAT I am thinking about solution:
I am thinking of keeping all struct variables names, sizes, type in a data structure, and slice byte stream in loop based on that
type datadetails struct {
name string //ex: uniqnum, guid etc
size int //9 ,32
datatype string //int, string, etc int for uniqnum, string for guid
}
Question: Need a better solution than that?
here is my sample, so far.
package main
import (
"bytes"
"encoding/gob"
"log"
"fmt"
)
type Test struct{
uniqnum int64 //9 char in byte stream ex: 708008123 (int)
guid string //exactly is 32 -chars
flag byte //string 1 char
printnum string //6 char
}
func convertintorec(data []byte) {
fmt.Println(data)
//convert byte data into Test record
}
func buffertoStruct(gbuffer []byte,pobj *Test ) {
tmp :=bytes.NewBuffer(gbuffer)
dec := gob.NewDecoder(tmp)
err := dec.Decode(pobj)
if err != nil {
log.Fatal("decode error:", err)
}
}
func main() {
bdata := []byte("9885455612guidstartshere12345678901234567F")
convertintorec(bdata)
}
This should get you halfway there:
var ErrTooShort = errors.New("too short")
func convertintorec(data []byte) (t *Test, err error) {
t = &Test{}
if len(data) < 9 {
err = ErrTooShort
return
}
uniqnum := string(data[:9])
t.uniqnum, err = strconv.ParseInt(uniqnum, 10, 64)
if err != nil {
err = fmt.Errorf("bad uniqnum %q: %w", uniqnum, err)
return
}
data = data[9:]
if len(data) < 32 {
err = fmt.Errorf("gid %w", ErrTooShort)
return
}
t.guid = string(data[:32])
// t.flag / t.printnum is left to implement...
return
}
https://play.golang.org/p/ZPzWC2IYjj1

C NULL type in CGO

I have a C function that returns NULL when an exception occurs. How can I check whether the returned value is NULL or not in Go since it has no built-in types to represent C NULL. Below is my code
retVal := C.myfunc()
if retVal == nil {
// handle the error
}
I think you can use nil to test if the c function returns NULL. Try the following code:
package main
/*
#include <stdio.h>
#include <stdlib.h>
int* cfunc(int i) {
if (i == 0) {
return NULL;
}
int *p = (int*)malloc(sizeof(int));
*p = 100;
return p;
}
*/
import "C"
import "fmt"
import "unsafe"
func call_cfunc(i int32) {
ret := C.cfunc(C.int(i))
if ret == nil {
fmt.Println("nil")
} else {
fmt.Println(*ret)
C.free(unsafe.Pointer(ret))
}
}
func main() {
call_cfunc(0)
call_cfunc(1)
}

convert a []float32 to C *float

I want to pass the pointer to the first element of a slice []float32 to a C variable, but somehow I can't figure out how.
C Code:
typedef struct
{ const float *data_in ;
float *data_out ;
} SRC_DATA ;
Go:
mySlice := make([]float32, 20)
foo := C.SRC_DATA{}
foo.data_in = *C.float(&mySlice[0]) // here the program breaks
As far as I have understood, it should be possible to pass directly a pointer to the first element in the slice from Go to C, without using unsafe.Pointer().
The C function will then iterate over the slice (length known).
Any hints are appreciated!
You need to use a slice of C.float type instead of float32:
package main
/*
#include <stdio.h>
void test(float *in) {
printf("C %f %f\n", in[0], in[1]);
}
*/
import "C"
func main() {
in := []C.float{1.23, 4.56}
C.test(&in[0]) // C 1.230000 4.560000
}
Go doesn't allow to store a Go pointer in a Go allocated structure passed to Cgo:
package main
/*
#include <stdio.h>
typedef struct {
float *in;
float *out;
} SRC_DATA;
void test(SRC_DATA *data) {
printf("C %f %f\n", data->in[0], data->in[1]);
data->out[0] = 8.8;
data->out[1] = 9.9;
}
*/
import "C"
import "fmt"
func main() {
in := []C.float{1.23, 4.56}
out := make([]C.float, 2)
data := &C.SRC_DATA{in: &in[0], out: &out[0]}
C.test(data) // panic: runtime error: cgo argument has Go pointer to Go pointer
fmt.Println("Go", out)
}
But you can create a helper function in C:
package main
/*
#include <stdio.h>
typedef struct {
float *in;
float *out;
} SRC_DATA;
void test(SRC_DATA *data) {
printf("C %f %f\n", data->in[0], data->in[1]);
data->out[0] = 8.8;
data->out[1] = 9.9;
}
void test_helper(float *in, float *out) {
SRC_DATA data;
data.in = in;
data.out = out;
test(&data);
}
*/
import "C"
import "fmt"
func main() {
in := []C.float{1.23, 4.56}
out := make([]C.float, 2)
C.test_helper(&in[0], &out[0]) // C 1.230000 4.560000
fmt.Println("Go", out) // Go [8.8 9.9]
}
Alternatively you can allocate and free SRC_DATA structure in C:
package main
/*
#include <stdio.h>
#include <stdlib.h>
typedef struct {
float *in;
float *out;
} SRC_DATA;
void test(SRC_DATA *data) {
printf("C %f %f\n", data->in[0], data->in[1]);
data->out[0] = 8.8;
data->out[1] = 9.9;
}
SRC_DATA *alloc_src_data() {
return (SRC_DATA*)malloc(sizeof(SRC_DATA));
}
void free_src_data(SRC_DATA *p) {
free(p);
}
*/
import "C"
import "fmt"
func main() {
in := []C.float{1.23, 4.56}
out := make([]C.float, 2)
data := C.alloc_src_data()
defer C.free_src_data(data)
data.in = &in[0]
data.out = &out[0]
C.test(data) // C 1.230000 4.560000
fmt.Println("Go", out) // Go [8.8 9.9]
}

Is there a way to find a process id on windows in Go?

In OS package there is a FindProcess() that you can pass in the ID of the process to get a process. You can then call kill on the process but is there a way to find a process based off of the name? (In windows)
For example i would like to be able to do something like this.
p, perr := os.FindProcessByName("Itunes")
if perr != nil {
fmt.Println(perr)
}
p.Kill()
I only need this to work on Windows.
It's not pretty, but you can use the w32 binding: (github.com/AllenDang/w32)
package main
import (
"fmt"
"github.com/AllenDang/w32"
"unsafe"
)
func GetProcessName(id uint32) string {
snapshot := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPMODULE, id)
if snapshot == w32.ERROR_INVALID_HANDLE {
return "<UNKNOWN>"
}
defer w32.CloseHandle(snapshot)
var me w32.MODULEENTRY32
me.Size = uint32(unsafe.Sizeof(me))
if w32.Module32First(snapshot, &me) {
return w32.UTF16PtrToString(&me.SzModule[0])
}
return "<UNKNOWN>"
}
func ListProcesses() []uint32 {
sz := uint32(1000)
procs := make([]uint32, sz)
var bytesReturned uint32
if w32.EnumProcesses(procs, sz, &bytesReturned) {
return procs[:int(bytesReturned)/4]
}
return []uint32{}
}
func FindProcessByName(name string) (uint32, error) {
for _, pid := range ListProcesses() {
if GetProcessName(pid) == name {
return pid, nil
}
}
return 0, fmt.Errorf("unknown process")
}
func main() {
fmt.Println(FindProcessByName("chrome.exe"))
}

Resources