校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

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

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

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

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

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

先大概說下什么是共享內(nèi)存。我們知道不同進(jìn)程見的內(nèi)存是互相獨(dú)立的,沒辦法直接互相操作對方內(nèi)的數(shù)據(jù),而共享內(nèi)存則是靠操作系統(tǒng)提供的內(nèi)存映射機(jī)制,讓不同進(jìn)程的一塊地址空間映射到同一個虛擬內(nèi)存區(qū)域上,使不同的進(jìn)程可以操作到一塊共用的內(nèi)存塊。共享內(nèi)存是效率最高的進(jìn)程間通訊機(jī)制,因?yàn)閿?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,沒辦法做我需求的指針運(yùn)算,所以我還是用cgo來調(diào)用原生的mmap。

實(shí)驗(yàn)分為讀和寫兩個程序,這樣我們可以觀察到讀進(jìn)程可以讀到寫進(jìn)程寫入共享內(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沒有實(shí)際占用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

因?yàn)閙map在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語言命令行操作命令詳細(xì)介紹
  • Go語言interface詳解
  • Go語言運(yùn)行環(huán)境安裝詳細(xì)教程
  • Go語言實(shí)現(xiàn)簡單的一個靜態(tài)WEB服務(wù)器
  • GO語言并發(fā)編程之互斥鎖、讀寫鎖詳解
  • GO語言標(biāo)準(zhǔn)錯誤處理機(jī)制error用法實(shí)例
  • Go語言中的內(nèi)存布局詳解

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

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Go語言共享內(nèi)存讀寫實(shí)例分析》,本文關(guān)鍵詞  語言,共享,內(nèi)存,讀寫,實(shí)例分析,;如發(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)存讀寫實(shí)例分析》相關(guān)的同類信息!
  • 本頁收集關(guān)于Go語言共享內(nèi)存讀寫實(shí)例分析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 齐河县| 石泉县| 丰原市| 青海省| 邢台市| 揭阳市| 花垣县| 乌兰察布市| 宿迁市| 蕉岭县| 马山县| 绿春县| 湘阴县| 桑日县| 昭苏县| 射阳县| 赤壁市| 瑞金市| 尼勒克县| 云梦县| 汕头市| 荔浦县| 德化县| 民丰县| 嘉禾县| 舟山市| 永川市| 鄯善县| 藁城市| 昆山市| 历史| 安岳县| 离岛区| 颍上县| 天镇县| 白玉县| 兴隆县| 乐昌市| 轮台县| 蛟河市| 正阳县|