欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2015年02月26日 15:32:23   作者:不是JS  
這篇文章主要介紹了Go語(yǔ)言共享內(nèi)存讀寫(xiě)方法,實(shí)例分析了共享內(nèi)存的原理與讀寫(xiě)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下

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

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

先大概說(shuō)下什么是共享內(nèi)存。我們知道不同進(jìn)程見(jiàn)的內(nèi)存是互相獨(dú)立的,沒(méi)辦法直接互相操作對(duì)方內(nèi)的數(shù)據(jù),而共享內(nèi)存則是靠操作系統(tǒng)提供的內(nèi)存映射機(jī)制,讓不同進(jìn)程的一塊地址空間映射到同一個(gè)虛擬內(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ù),它可以將一個(gè)文件映射到虛擬內(nèi)存的一個(gè)區(qū)域中,程序使用指針引用這個(gè)區(qū)域,對(duì)這個(gè)內(nèi)存區(qū)域的操作會(huì)被回寫(xiě)到文件上,Go內(nèi)置的syscall包中有mmap函數(shù),但是它是經(jīng)過(guò)封裝的,返回的是[]byte,沒(méi)辦法做我需求的指針運(yùn)算,所以我還是用cgo來(lái)調(diào)用原生的mmap。

實(shí)驗(yàn)分為讀和寫(xiě)兩個(gè)程序,這樣我們可以觀察到讀進(jìn)程可以讀到寫(xiě)進(jìn)程寫(xiě)入共享內(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)存,用來(lái)證明mmap沒(méi)有實(shí)際占用4G內(nèi)存,而是用到了虛擬內(nèi)存。

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

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

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

因?yàn)閙map在Mac上不需要連接librt,在linux上則需要,所以做了一個(gè)條件鏈接,這是cgo提供的功能。

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

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

相關(guān)文章

  • 從錯(cuò)誤中學(xué)習(xí)改正Go語(yǔ)言六個(gè)壞習(xí)慣提高編程技巧

    從錯(cuò)誤中學(xué)習(xí)改正Go語(yǔ)言六個(gè)壞習(xí)慣提高編程技巧

    這篇文章主要為大家介紹了從錯(cuò)誤中學(xué)習(xí)改正Go語(yǔ)言五個(gè)壞習(xí)慣提高編程技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • go中實(shí)現(xiàn)字符切片和字符串互轉(zhuǎn)

    go中實(shí)現(xiàn)字符切片和字符串互轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了go語(yǔ)言中如何實(shí)現(xiàn)字符切片和字符串互轉(zhuǎn),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-11-11
  • Go?分布式鏈路追蹤實(shí)現(xiàn)原理解析

    Go?分布式鏈路追蹤實(shí)現(xiàn)原理解析

    分布式鏈路追蹤作為解決分布式應(yīng)用可觀測(cè)問(wèn)題的重要技術(shù),愈發(fā)成為分布式應(yīng)用不可缺少的基礎(chǔ)設(shè)施,本文將詳細(xì)介紹分布式鏈路的核心概念、架構(gòu)原理和相關(guān)開(kāi)源標(biāo)準(zhǔn)協(xié)議,并分享我們?cè)趯?shí)現(xiàn)無(wú)侵入 Go 采集 Sdk 方面的一些實(shí)踐,需要的朋友可以參考下
    2022-06-06
  • golang中struct和[]byte的相互轉(zhuǎn)換示例

    golang中struct和[]byte的相互轉(zhuǎn)換示例

    這篇文章主要介紹了golang中struct和[]byte的相互轉(zhuǎn)換示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 一篇文章說(shuō)清楚?go?get?使用私有庫(kù)的方法

    一篇文章說(shuō)清楚?go?get?使用私有庫(kù)的方法

    這篇文章主要介紹了go?get?如何使用私有庫(kù),本文會(huì)明確指出Git?、golang的配置項(xiàng),附送TortoiseGit?+?Git混合配置,需要的朋友可以參考下
    2022-09-09
  • go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理解析

    go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理解析

    這篇文章主要介紹了go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理,這里提供一個(gè)通過(guò)docker快速安裝Consul的方式,當(dāng)然前提是你得安裝了docker,需要的朋友可以參考下
    2022-04-04
  • 重學(xué)Go語(yǔ)言之如何使用Modules

    重學(xué)Go語(yǔ)言之如何使用Modules

    Go語(yǔ)言在Go.1.11版本發(fā)布了Go?Modules,這是一種新的Go項(xiàng)目依賴(lài)管理解決方案,可以讓Go項(xiàng)目的依賴(lài)包關(guān)系更加清晰,也更容易管理,下面就來(lái)看看Modules是如何使用的吧
    2023-07-07
  • Golang接口使用教程詳解

    Golang接口使用教程詳解

    在?Go?語(yǔ)言中接口包含兩種含義:它既是方法的集合,?同時(shí)還是一種類(lèi)型并且在Go?語(yǔ)言中是隱式實(shí)現(xiàn)的。本文通過(guò)示例詳細(xì)介紹了Golang接口的使用,需要的可以參考一下
    2022-09-09
  • golang如何使用sarama訪問(wèn)kafka

    golang如何使用sarama訪問(wèn)kafka

    這篇文章主要介紹了golang如何使用sarama訪問(wèn)kafka,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • Go計(jì)算某段代碼運(yùn)行所耗時(shí)間簡(jiǎn)單實(shí)例

    Go計(jì)算某段代碼運(yùn)行所耗時(shí)間簡(jiǎn)單實(shí)例

    這篇文章主要給大家介紹了關(guān)于Go計(jì)算某段代碼運(yùn)行所耗時(shí)間的相關(guān)資料,主要介紹了Golang記錄計(jì)算函數(shù)執(zhí)行耗時(shí)、運(yùn)行時(shí)間的一個(gè)簡(jiǎn)單方法,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-11-11

最新評(píng)論