1. 程式人生 > >golang 結合cgo 操作共享記憶體,包括虛擬記憶體mmap版和記憶體shm版

golang 結合cgo 操作共享記憶體,包括虛擬記憶體mmap版和記憶體shm版

如下是原始碼實現直接編譯即可使用:

//author sam by 20170621
// 使用示例:
// package utils

// import (
//  "fmt"
//  u "lpaiche.com/utils"
//  "testing"
// )

// type MyData struct {
//  Col1 int
//  Col2 int
//  Col3 int
//  Col4 int
// }

// //-----------------------------------------test_mmap_shm----------------------------
// func TestWriteMmapShm(t *testing.T) {
// shm := u.NewShmMmap("test") // fmt.Println(shm) // fmt.Println("寫入共享記憶體") // data := (*MyData)(shm.GetWritePointer()) // data.Col1 = 105 // data.Col2 = 276 // data.Col3 = 2021 // data.Col4 = 2020 // fmt.Println(data) // } // func TestReadMmapShm(t *testing.T) { // fmt.Println("讀取共享記憶體") // shm := u.NewShmMmap("test")
// data1 := (*MyData)(shm.GetReadPointer()) // fmt.Println(data1) // } // func TestFreeMmapShm(t *testing.T) { // fmt.Println("刪除共享記憶體") // shm := u.NewShmMmap("test") // shm.Remove() // } // //-------------------------------------------test_mem_shm------------------------ // func TestShmmemGetWritePointer(t *testing.T) {
// shm := u.NewShmMem("/tmp/shm") // fmt.Println(shm) // data := (*MyData)(shm.GetWritePointer()) // defer shm.Close() // data.Col1 = 1111 // data.Col2 = 2222 // data.Col3 = 3333 // data.Col4 = 4444 // fmt.Println(data) // } // func TestShmmemGetReadPointer(t *testing.T) { // fmt.Println("讀取共享記憶體") // shm := u.NewShmMem("/tmp/shm") // data1 := (*MyData)(shm.GetReadPointer()) // fmt.Println(data1) // } // func TestShmmemRemove(t *testing.T) { // shm := u.NewShmMem("/tmp/shm") // fmt.Println("刪除共享記憶體") // shm.Remove() // } package utils /* #cgo linux LDFLAGS: -lrt #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> //-----------------cgo_mmap---------------------------- #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int my_shm_new(char *name) { //shm_unlink(name); return shm_open(name, O_RDWR|O_CREAT|O_EXCL, FILE_MODE); } int my_shm_open(char *name) { return shm_open(name, O_RDWR, FILE_MODE); } void my_shm_free(char *name){ shm_unlink(name); } //------------------cgo_shm------------------------- int my_shmmem_open(char *file,int size,int open_flag){ int shm_id; key_t key; key = ftok(file, 0x111); if(key == -1){ return -1; } if(open_flag) shm_id = shmget(key, size, IPC_CREAT|IPC_EXCL|0600); else shm_id = shmget(key, 0, 0); if(shm_id == -1){ return -1; } return shm_id; } int my_shmmem_rm(int shm_id){ shmctl(shm_id, IPC_RMID, NULL); return 0; } */ import "C" import ( "fmt" "unsafe" ) //------------------------------mmap實現共享記憶體操作------------------------------------------------------------- type ShmMmap struct { name string size int } func NewShmMmap(shm_name string, shm_size ...int) *ShmMmap { shm_size1 := 1 * 1000 * 1000 * 1000 //預設共享記憶體大小1G if shm_size != nil { shm_size1 = shm_size[0] } shmm := ShmMmap{name: shm_name, size: shm_size1} return &shmm } func (this *ShmMmap) GetWritePointer() unsafe.Pointer { this.Remove() fd, err := C.my_shm_new(C.CString(this.name)) if err != nil { fmt.Println(err) return nil } shm_size := (C.__off_t)(this.size) C.ftruncate(fd, shm_size) ptr, err := C.mmap(nil, 4*1000*1000*1000, C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED, fd, 0) if err != nil { fmt.Println(err) return nil } C.close(fd) return (unsafe.Pointer(ptr)) } func (this *ShmMmap) Remove() { C.my_shm_free(C.CString(this.name)) } func (this *ShmMmap) GetReadPointer() unsafe.Pointer { fd, err := C.my_shm_open(C.CString(this.name)) if err != nil { fmt.Println(err) return nil } shm_size := (C.size_t)(this.size) ptr, err := C.mmap(nil, shm_size, C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED, fd, 0) if err != nil { fmt.Println(err) return nil } C.close(fd) return (unsafe.Pointer(ptr)) } //---------------------------------------shm實現共享記憶體操作------------------------------------------ type ShmMem struct { filename string size int shmid int pointer unsafe.Pointer } func NewShmMem(pathfilename string, shm_size ...int) *ShmMem { shm_size1 := 4096 //預設共享記憶體大小4k if shm_size != nil { shm_size1 = shm_size[0] } shmm := ShmMem{filename: pathfilename, size: shm_size1, shmid: 0} return &shmm } func (this *ShmMem) initShmit() { filename := C.CString(this.filename) defer C.free(unsafe.Pointer(filename)) this.shmid = int(C.my_shmmem_open(filename, C.int(this.size), C.int(1))) if this.shmid < 0 { this.shmid = int(C.my_shmmem_open(filename, C.int(this.size), C.int(0))) } if this.shmid < 0 { fmt.Println("open share memery failed!") Panic("open share memery failed! ") } } func (this *ShmMem) GetWritePointer() unsafe.Pointer { this.initShmit() addr := C.shmat(C.int(this.shmid), nil, 0) this.pointer = unsafe.Pointer(addr) return this.pointer } func (this *ShmMem) GetReadPointer() unsafe.Pointer { return this.GetWritePointer() } func (this *ShmMem) Close() { C.shmdt(this.pointer) } func (this *ShmMem) Remove() { this.initShmit() C.my_shmmem_rm(C.int(this.shmid)) }

相關推薦

golang 結合cgo 操作共享記憶體,包括虛擬記憶體mmap記憶體shm

如下是原始碼實現直接編譯即可使用: //author sam by 20170621 // 使用示例: // package utils // import ( // "fmt" // u "lpaiche.com/utils" // "testi

Android虛擬機器的理解記憶體管理

虛擬機器很小,空間很小,談談移動裝置的虛擬機器的大小限制 16M ,談談載入圖片的時候怎麼處理大圖片的,outmemoryExceptionBitmapFactory.option 垃圾回收,沒有引用的物件,在某個時刻會被系統gc掉 .Dalvik和標準Java虛擬機器(JV

SSD: Single Shot MultiBox Detector翻譯(包括正式預印)(對原文作部分理解性修改)

預印版表7 表7:Pascal VOC2007 test上的結果。SSD300是唯一的可以實現超過70%mAP的實時檢測方法。通過使用大輸入影象,在保持接近實時速度的同時,SSD512在精度上優於所有方法。 4、相關工作         目前有兩種已建立的用於影象中物件檢測的方法,一種基於

記憶體洩漏(memory leak)記憶體溢位(out of memory)

一、概念: memory leak---記憶體洩漏:是指程式申請記憶體空間後,無法釋放。然而,記憶體洩漏不斷疊加會導致系統把記憶體花完,以致於發生記憶體溢位。(用了不還) out of memory-

win7下的虛擬機器ubuntu系統的記憶體共享

1、在windows下建立一個資料夾(winShare)來作為共享資料夾,路徑為F:\winShare 2、在VMware Workstation上選中虛擬機器->設定->選項, 3、在windows桌面用滑鼠右擊計算機(或我的電腦)->對映

mysql數據庫結合pam_mysql模塊實現vsftpd虛擬用戶

mysql vsftp pam mysql數據庫結合pam_mysql模塊實現vsftpd虛擬用戶登錄最近開始學mysql,自己做一個小實驗,來個總結,比較容易理解,沒什麽太多理論性的東西。一、實驗環境的準備1. 先下載需要用到的軟件和依賴包[[email protected]/* *

springmvc結合ehcache實現共享對象緩存

bsp 技術 name size b2c 接下來 pom etc log   筆者最近在學習Web性能優化的知識,想用springmvc結合ehcache來實現共享對象緩存,可是網上的很多教程講得不是很清楚,加上本人對spring的知識還沒有完全熟悉,所以在實現過程中碰到了

操作系統(6)_虛擬存儲管理_李善平ppt

ima image http bsp src com 管理 操作系統 操作 image含各種段。 操作系統(6)_虛擬存儲管理_李善平ppt

Golang之Mysql操作

set ron display imp lan fun 圖片 try 增刪改 話說當年武大郎對著電腦一頓劈裏啪啦,,,對mysql增刪改查 增加insert package main import ( "fmt" "github.com

Apache與PHP的結合配置、Apache默認虛擬主機

LinuxApache和PHP結合配置httpd支持php1. 修改配置文件:[root@gary-tao php-7.1.6]# vim /usr/local/apache2.4/conf/httpd.conf修改一:修改httpd的主配置文件/usr/local/apache2.4/conf/httpd.

4.12任務 apache結合php以及apache默認虛擬主機

apache php apache虛擬主機 apache和php結合 雖然我們現在已經安裝好了apache,mysql,php。但是我們還沒有讓他們結合起來,雖然apache調用了php作為它的一個模塊,但我們還不知道他是否能解析php。這時我們還需要去編輯一下httpd的配置文件。 它的配置文件

尚矽谷大數據技術之Linux第5章網絡配置系統管理操作5.7克隆虛擬

tro 分享 數據 time 克隆 sys font pic get 5.7 克隆虛擬機 1)關閉要被克隆的虛擬機 2)找到克隆選項 3)歡迎頁面 4)克隆虛擬機 5)設置創建完整克隆 6)設置克隆的虛擬機名稱和存儲位置 7)等待正在克隆 8)點擊關閉,完成克

apachephp結合、apache的默認虛擬主機

rtu his 解析 -a director rom 虛擬 rac extra 一:apache和php結合 修改 apache 配置文件#vi /usr/local/apache2/conf/httpd.conf找到:<Directory />Options

多執行緒原子操作記憶體柵欄(二)

        這裡記錄下各種鎖的使用和使用場景,在多執行緒場景開發時,我們經常遇到多個執行緒同時讀寫一塊資源爭搶一塊資源的情況,比如同時讀寫同一個欄位屬性,同時對某個集合進行增刪改查,同時對資料庫進行讀寫(這裡

多執行緒原子操作記憶體柵欄(一)

執行緒的定義是執行流的最小單元,而程序是一個邏輯執行緒容器,用來隔離執行緒。 Task類封裝了執行緒池執行緒,啟動的所有線都由執行緒池管理,他提供了很多使用方便的API函式,使多執行緒開發變得容易。 上述程式碼中我啟動了一個執行緒,並在執行緒方法中使用了非同步關鍵字,非同步方法實現了一個狀態

三、Java虛擬機器自動記憶體管理機制、物件建立及記憶體分配

  1、物件是如何建立: 步驟:    (1)、虛擬機器遇到new <類名>的指令---->根據new的引數是否在常量池中定位一個類的符號引用    (2)、檢測該符號引用代表的類是否已經被載入、解析、和初始化。(如果沒有則

011-golang檔案複製操作

  最近開始學golang 來寫一個golang裡的檔案複製操作吧   一共7個步驟就搞定了 //func main() { // // file1, err1 := os.Open("./andy.jpg") // file2, err2 := os.C

linux記憶體管理---虛擬地址 邏輯地址 線性地址 實體地址的區別(一)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C# 操作共享資料夾

/// <summary> /// 共享檔案操作類 /// </summary> public class SharedFolderManager { public SharedFolderManager() { // //TODO: 在