濮阳杆衣贸易有限公司

主頁 > 知識庫 > Go語言共享內(nèi)存讀寫實例分析

Go語言共享內(nèi)存讀寫實例分析

熱門標(biāo)簽:海外照相館地圖標(biāo)注入駐 經(jīng)常接到推銷電話機器人的電話 客服級電銷機器人 外呼系統(tǒng)多少錢一年 外呼系統(tǒng)如何接收服務(wù)密碼 智能營銷軟件 旅游廁所如何電子地圖標(biāo)注 滁州自建外呼系統(tǒng) 工商信用卡外呼系統(tǒng)教程

本文實例分析了Go語言共享內(nèi)存讀寫的方法。分享給大家供大家參考。具體分析如下:

前面分析了Go語言指針運算和內(nèi)嵌C代碼的方法,做了一個Go語言共享內(nèi)存讀寫的實驗。

先大概說下什么是共享內(nèi)存。我們知道不同進程見的內(nèi)存是互相獨立的,沒辦法直接互相操作對方內(nèi)的數(shù)據(jù),而共享內(nèi)存則是靠操作系統(tǒng)提供的內(nèi)存映射機制,讓不同進程的一塊地址空間映射到同一個虛擬內(nèi)存區(qū)域上,使不同的進程可以操作到一塊共用的內(nèi)存塊。共享內(nèi)存是效率最高的進程間通訊機制,因為數(shù)據(jù)不需要在內(nèi)核和程序之間復(fù)制。

共享內(nèi)存用到的是系統(tǒng)提供的mmap函數(shù),它可以將一個文件映射到虛擬內(nèi)存的一個區(qū)域中,程序使用指針引用這個區(qū)域,對這個內(nèi)存區(qū)域的操作會被回寫到文件上,Go內(nèi)置的syscall包中有mmap函數(shù),但是它是經(jīng)過封裝的,返回的是[]byte,沒辦法做我需求的指針運算,所以我還是用cgo來調(diào)用原生的mmap。

實驗分為讀和寫兩個程序,這樣我們可以觀察到讀進程可以讀到寫進程寫入共享內(nèi)存的信息。

下面是shm_writer.go的代碼:

復(fù)制代碼 代碼如下:
package main
/*
#cgo linux LDFLAGS: -lrt
#include fcntl.h>
#include unistd.h>
#include sys/mman.h>
#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);
}
*/
import "C"
import (
    "fmt"
    "unsafe"
)
const SHM_NAME = "my_shm"
const SHM_SIZE = 4 * 1000 * 1000 * 1000
type MyData struct {
    Col1 int
    Col2 int
    Col3 int
}
func main() {
    fd, err := C.my_shm_new(C.CString(SHM_NAME))
    if err != nil {
        fmt.Println(err)
        return
    }
    C.ftruncate(fd, SHM_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
    }
    C.close(fd)
    data := (*MyData)(unsafe.Pointer(ptr))
    data.Col1 = 100
    data.Col2 = 876
    data.Col3 = 8021
}

下面是shm_reader.go的代碼:

復(fù)制代碼 代碼如下:
package main
/*
#cgo linux LDFLAGS: -lrt
#include fcntl.h>
#include unistd.h>
#include sys/mman.h>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int my_shm_open(char *name) {
    return shm_open(name, O_RDWR);
}
*/
import "C"
import (
    "fmt"
    "unsafe"
)
const SHM_NAME = "my_shm"
const SHM_SIZE = 4 * 1000 * 1000 * 1000
type MyData struct {
    Col1 int
    Col2 int
    Col3 int
}
func main() {
    fd, err := C.my_shm_open(C.CString(SHM_NAME))
    if err != nil {
        fmt.Println(err)
        return
    }
    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
    }
    C.close(fd)
    data := (*MyData)(unsafe.Pointer(ptr))
    fmt.Println(data)
}

上面的程序映射了一塊4G的虛擬內(nèi)存,用來證明mmap沒有實際占用4G內(nèi)存,而是用到了虛擬內(nèi)存。

shm_writer創(chuàng)建好共享內(nèi)存以后,往內(nèi)存區(qū)域?qū)懭肓艘粋€結(jié)構(gòu)體,shm_reader則讀出一個結(jié)構(gòu)體。

內(nèi)嵌的C代碼中有一行 :

復(fù)制代碼 代碼如下:
#cgo linux LDFLAGS: -lrt

因為mmap在Mac上不需要連接librt,在linux上則需要,所以做了一個條件鏈接,這是cgo提供的功能。

上面代碼中還用到一個cgo的技巧,像shm_open和mmap函數(shù)在錯誤時會返回errno,如果我們在go中使用多返回值語法,cgo會自己把錯誤碼轉(zhuǎn)換成錯誤信息,很方便的功能。

希望本文所述對大家的Go語言程序設(shè)計有所幫助。

您可能感興趣的文章:
  • Golang 內(nèi)存模型詳解(一)
  • Go語言中的Array、Slice、Map和Set使用詳解
  • Go語言的GOPATH與工作目錄詳解
  • Go語言命令行操作命令詳細介紹
  • Go語言interface詳解
  • Go語言運行環(huán)境安裝詳細教程
  • Go語言實現(xiàn)簡單的一個靜態(tài)WEB服務(wù)器
  • GO語言并發(fā)編程之互斥鎖、讀寫鎖詳解
  • GO語言標(biāo)準(zhǔn)錯誤處理機制error用法實例
  • Go語言中的內(nèi)存布局詳解

標(biāo)簽:深圳 楚雄 喀什 湘潭 九江 本溪 晉城 運城

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Go語言共享內(nèi)存讀寫實例分析》,本文關(guān)鍵詞  語言,共享,內(nèi)存,讀寫,實例分析,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Go語言共享內(nèi)存讀寫實例分析》相關(guān)的同類信息!
  • 本頁收集關(guān)于Go語言共享內(nèi)存讀寫實例分析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    卫辉市| 施秉县| 台中市| 株洲县| 武平县| 罗田县| 长顺县| 昭苏县| 潼南县| 抚远县| 临澧县| 津南区| 宜丰县| 综艺| 分宜县| 洱源县| 抚州市| 沅陵县| 山阳县| 多伦县| 团风县| 石阡县| 连南| 突泉县| 灵石县| 固安县| 扎囊县| 微山县| 和顺县| 汉中市| 大新县| 南安市| 乐都县| 衡山县| 双鸭山市| 张北县| 东阳市| 翁源县| 台中市| 广灵县| 永和县|