最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

本文實(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è)計(jì)有所幫助。

相關(guān)文章

  • Go基于struct?tag實(shí)現(xiàn)結(jié)構(gòu)體字段級別的訪問控制

    Go基于struct?tag實(shí)現(xiàn)結(jié)構(gòu)體字段級別的訪問控制

    本文將會基于這個主題展開,討論Go中的結(jié)構(gòu)體tag究竟是什么,我們該如何利用它,另外,文末還提供了一個實(shí)際案例,實(shí)現(xiàn)結(jié)構(gòu)體字段級別的訪問,幫助我們進(jìn)一步提升對struct tag的理解
    2024-02-02
  • go并發(fā)編程sync.Cond使用場景及實(shí)現(xiàn)原理

    go并發(fā)編程sync.Cond使用場景及實(shí)現(xiàn)原理

    這篇文章主要為大家介紹了go并發(fā)編程sync.Cond使用場景及實(shí)現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang中由零值和gob庫特性引起B(yǎng)UG解析

    Golang中由零值和gob庫特性引起B(yǎng)UG解析

    這篇文章主要為大家介紹了Golang中由零值和gob庫特性引起B(yǎng)UG解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Go語言操作mysql數(shù)據(jù)庫簡單例子

    Go語言操作mysql數(shù)據(jù)庫簡單例子

    這篇文章主要介紹了Go語言操作mysql數(shù)據(jù)庫簡單例子,本文包含插入數(shù)據(jù)和查詢代碼實(shí)例,需要的朋友可以參考下
    2014-10-10
  • Go語言fmt.Sprintf格式化輸出的語法與實(shí)例

    Go語言fmt.Sprintf格式化輸出的語法與實(shí)例

    Go 可以使用 fmt.Sprintf 來格式化字符串,下面這篇文章主要給大家介紹了關(guān)于Go語言fmt.Sprintf格式化輸出的語法與實(shí)例,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Go 語言單例模式示例詳解

    Go 語言單例模式示例詳解

    這篇文章主要為大家介紹了Go 語言單例模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 最新評論

    文登市| 疏附县| 英吉沙县| 荥阳市| 大方县| 肇庆市| 开远市| 宜宾市| 新邵县| 横峰县| 肥西县| 南城县| 巴林左旗| 天祝| 叙永县| 泗阳县| 山阳县| 荆门市| 涟水县| 且末县| 上饶县| 平顺县| 遵义市| 武宁县| 大港区| 东安县| 涞源县| 枣阳市| 宜兰县| 红安县| 白银市| 嘉鱼县| 昌宁县| 广丰县| 灌阳县| 和政县| 盐山县| 铜陵市| 五华县| 荣昌县| 罗平县|