Here is my code. package main /* #include <string.h> #include <stdio.h> #include <stdlib.h> static void memcpy_c(char *dest, int offs1, char *src, int offs2, int cnt) { if (src == 0 || dest == 0) { printf("a null ptr.\n"); return; } int a = 0; long i = 0; memcpy(dest + offs1, src+offs2, cnt); while (1){ if (i >= cnt) { break; } i++; } char tmp[] = "yesss"; printf("a null ptr.%d, %d,%ld,%ld\n", offs1, offs2, dest, src); } static void set_int32(char *addr, int offset, int num) { int* d = (int *)(addr + 4 * offset); *d = num; } static int get_int32(char *addr, int offset) { int *d = (int *)(addr + 4 * offset); return *d; } static void get_data(char *addr, int offset, int cnt) { char tmp[cnt]; memcpy(tmp, addr+offset, cnt); printf("get data%s", tmp); } */ import "C" import ( "fmt" "github.com/go-ini/ini" "math/rand" "strconv" "syscall" "unsafe" )
//memcpy(dest + offs1, tmp, 5); //printf("%d, %d\n", *(dest + offs1+i), *(src+offs2+i)); const ( // IpcCreate create if key nonexistent IpcCreate = 00001000 ) type MemPoolMng struct { data_start_ptr uintptr offs_start_ptr uintptr offs_key uintptr data_key uintptr data_cnt int mem_helper unsafe.Pointer } func NewMemPoolMng() *MemPoolMng { return &MemPoolMng{} } func (mp_mgr *MemPoolMng) Init() bool { cfg, err := ini.Load("./cfg.ini") if err != nil { return false } tmp_offs_key, err1 := strconv.Atoi(cfg.Section("mempool").Key("offs_key").String()) tmp_data_key, err2 := strconv.Atoi(cfg.Section("mempool").Key("data_key").String()) if err1 != nil { return false } if err2 != nil { return false } //get share memory from shmid. offs_id, _, err3 := syscall.Syscall(syscall.SYS_SHMGET, uintptr(tmp_offs_key), 1<<32, IpcCreate|0600) data_id, _, err4 := syscall.Syscall(syscall.SYS_SHMGET, uintptr(tmp_data_key), 1<<15, IpcCreate|0600) if err3 != 0 { return false } if err4 != 0 { return false } mp_mgr.offs_key = offs_id mp_mgr.data_key = data_id mp_mgr.mem_helper = C.malloc(1 << 32) // Share memory struct: |data_size(4)| offset1 | offset2 | offset3 |... offs_shmaddr, _, err5 := syscall.Syscall(syscall.SYS_SHMAT, offs_id, 0, 0) if err5 != 0 { return false } defer syscall.Syscall(syscall.SYS_SHMDT, offs_shmaddr, 0, 0) mp_mgr.data_cnt = *(*int)(unsafe.Pointer(uintptr(offs_shmaddr))) fmt.Printf("MemPoolMng init success(%d).\n", mp_mgr.data_cnt) return true } // Save the offset of each data with a contiguous address. |data_cnt|0|offsset1|offset2|......| func (mp_mgr *MemPoolMng) PutData(data *[]byte) bool { if mp_mgr.data_cnt >= 1024 || len(*data) == 0 { return false } offs_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.offs_key, 0, 0) //data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, uintptr(mp_mgr.mem_helper), 0) data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 0, 0) defer syscall.Syscall(syscall.SYS_SHMDT, offs_shmaddr, 0, 0) defer syscall.Syscall(syscall.SYS_SHMDT, data_shmaddr, 0, 0) data_cnt := *(*int)(unsafe.Pointer(uintptr(offs_shmaddr))) per_offs := C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), C.int(data_cnt+1)) // step 1: Put data. //C.memcpy_c((*C.char)(mp_mgr.mem_helper), per_offs, (C.CString)(string(*data)), 0, C.int(len(*data))) C.memcpy_c((*C.char)(unsafe.Pointer(data_shmaddr)), per_offs, (C.CString)(string(*data)), 0, C.int(len(*data))) //C.memcpy(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), unsafe.Pointer((C.CString)(string(*data))), C.ulong(len(*data))) //C.memcpy(unsafe.Pointer(data_shmaddr), unsafe.Pointer((C.CString)(string(*data))), 48000) // step 2: Modify offset. cur_offs := int(per_offs) + len(*data) C.set_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), C.int(data_cnt+2), C.int(cur_offs)) // step 3: Modify data_cnt data_cnt += 1 *(*int)(unsafe.Pointer(uintptr(offs_shmaddr))) = data_cnt //C.memcpy_c((*C.char)(unsafe.Pointer(data_shmaddr)), (*C.char)(unsafe.Pointer(offs_shmaddr)), 4) //for i := 0; i <= data_cnt+2; i++ { for i := 0; i <= -1; i++ { fmt.Printf("%d ", C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), C.int(i))) } for i := 0; i < 10; i++ { // fmt.Println(C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr+uintptr(data_cnt-i))), 0)) } return true } func (mp_mgr *MemPoolMng) GetData() []byte { offs_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.offs_key, 0, 0) syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 0, 0) data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 0, 0) //data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, uintptr(mp_mgr.mem_helper), 0) data_cnt := *(*int)(unsafe.Pointer(uintptr(offs_shmaddr))) if data_cnt == 0 { return []byte{} } // Generate a probability based on the insertion time of the data. The last one has probability n/(1+2+...+n). total := data_cnt * (data_cnt + 1) / 2 random := rand.Intn(total) + 1 data_i := 0 for i := 1; i <= data_cnt; i++ { a := i * (i - 1) / 2 b := i * (i + 1) / 2 if random > a && random <= b { data_i = i break } } per_offs := C.get_int32((*C.char)(unsafe.Pointer(uintptr(offs_shmaddr))), C.int(data_i)) cur_offs := C.get_int32((*C.char)(unsafe.Pointer(uintptr(offs_shmaddr))), C.int(data_i+1)) if cur_offs <= per_offs { return []byte{} } record := C.GoBytes(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), cur_offs-per_offs) //record := C.GoBytes(unsafe.Pointer(uintptr(mp_mgr.mem_helper)+uintptr(per_offs)), cur_offs-per_offs) fmt.Println(cur_offs-per_offs, len(record)) if len(record) > 10 { return record[:10] } return record } 在 2019年3月19日星期二 UTC+8上午11:51:48,Ian Lance Taylor写道: > > On Mon, Mar 18, 2019 at 8:17 PM <6159...@qq.com <javascript:>> wrote: > > > > shmid, _, err := syscall.Syscall(syscall.SYS_SHMGET, uintptr(10001), > 1<<32, IpcCreate|0600) > > data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, shmid, 0, 0) > > C.memcpy(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), > unsafe.Pointer((C.CString)(string(*data))), C.ulong(len(*data))) > > > > I'm trying to use syscall shmat/shmget, but it seems like i can't map > all the address that i wanted. > > 'per_offs' is a int value far less than 1<<32, below is what i got. > > > > fatal error: unexpected signal during runtime execution > > [signal SIGSEGV: segmentation violation code=0x1 addr=0x7fe3502cca80 > pc=0x7fe34d9320b4] > > > > runtime stack: > > runtime.throw(0x552be5, 0x2a) > > /data1/user1/go_env/go/src/runtime/panic.go:619 +0x81 > > runtime.sigpanic() > > /data1/user1/go_env/go/src/runtime/signal_unix.go:372 +0x28e > > > > goroutine 1 [syscall]: > > runtime.cgocall(0x4fe960, 0xc4200edd40, 0x29) > > /data1/user1/go_env/go/src/runtime/cgocall.go:128 +0x64 fp=0xc4200edd00 > sp=0xc4200edcc8 pc=0x403034 > > main._Cfunc_memcpy(0x7fe3502cca80, 0x7fe3440008c0, 0x1, 0x0) > > _cgo_gotypes.go:78 +0x4e fp=0xc4200edd40 sp=0xc4200edd00 pc=0x4fdb7e > > main.(*MemPoolMng).PutData.func1(0x7fe3502cca80, 0x7fe3440008c0, 0x1, > 0x1) > > /data1/user2/GoServer/mempool_go/mempool_mgr.go:107 +0x99 > fp=0xc4200edd78 sp=0xc4200edd40 pc=0x4fe7a9 > > main.(*MemPoolMng).PutData(0xc4200182d0, 0xc420158000, 0xf4240) > > /data1/user2/GoServer/mempool_go/mempool_mgr.go:107 +0x1da > fp=0xc4200ede58 sp=0xc4200edd78 pc=0x4fe37a > > main.handleProtoClient(0x565720, 0xc42000e060) > > /data1/user2/GoServer/mempool_go/server.go:58 +0x16f fp=0xc4200eded0 > sp=0xc4200ede58 pc=0x4fcf8f > > main.main() > > /data1/user2/GoServer/mempool_go/server.go:39 +0x261 fp=0xc4200edf88 > sp=0xc4200eded0 pc=0x4fcca1 > > runtime.main() > > /data1/user1/go_env/go/src/runtime/proc.go:198 +0x212 fp=0xc4200edfe0 > sp=0xc4200edf88 pc=0x42b772 > > runtime.goexit() > > /data1/user1/go_env/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc4200edfe8 > sp=0xc4200edfe0 pc=0x455601 > > exit status 2 > > > 1) Always check the returned error value. > > 2) Show us a complete, standalone, program. > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.