真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言h2demo Go語言并發(fā)

【原創(chuàng)】樹莓派3B開發(fā)Go語言(四)-自寫庫實(shí)現(xiàn)pwm輸出

在前一小節(jié)中介紹了點(diǎn)亮第一個LED燈,這里我們準(zhǔn)備進(jìn)階嘗試下,輸出第一段PWM波形。(PWM也就是脈寬調(diào)制,一種可調(diào)占空比的技術(shù),得到的效果就是:如果用示波器測量引腳會發(fā)現(xiàn)有方波輸出,而且高電平、低電平的時間是可調(diào)的。)

公司主營業(yè)務(wù):成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出寧鄉(xiāng)免費(fèi)做網(wǎng)站回饋大家。

這里爪爪熊準(zhǔn)備寫成一個golang的庫,并開源到github上,后續(xù)更新將直接更新到github中,如果你有興趣可以和我聯(lián)系。 github.com/dpawsbear/bear_rpi_go

我在很多的教程中都看到說樹莓派的PWM(硬件)只有一個GPIO能夠輸出,就是 GPIO1 。這可是不小的打擊,因為我想使用至少四個 PWM ,還是不死心,想通過硬件手冊上找尋蛛絲馬跡,看看究竟怎么回事。

手冊上找尋東西稍等下講述,這里先提供一種方法測試 樹莓派3B 的 PWM 方法:用指令控制硬件PWM。

這里通過指令的方式掌握了基本的pwm設(shè)置技巧,決定去翻一下手冊看看到底PWM怎么回事,這里因為沒有 BCM2837 的手冊,根據(jù)之前文章引用官網(wǎng)所說, BCM2835 和 BCM2837 應(yīng)該是一樣的。這里我們直接翻閱 BCM2835 的手冊,直接找到 PWM 章節(jié)。找到了如下圖:

圖中可以看到在博通的命名規(guī)則中 GPIO 12、13、18、19、40、41、45、52、53 均可以作為PWM輸出。但是只有兩路PWM0 PWM1。根據(jù)我之前所學(xué)知識,不出意外應(yīng)該是PWM0 和 PWM1可以輸出不一樣的占空比,但是頻率應(yīng)該是一樣的。因為沒有示波器,暫時不好測試。先找到下面對應(yīng)圖:

根據(jù)以上兩個圖對比可以發(fā)現(xiàn)如下規(guī)律:

對照上面的表可以看出從 BCM2837 中印出來的能夠使用在PWM上的就這幾個了。

為了驗證個人猜想是否正確,這里先直接使用指令的模式,模擬配置下是否能夠正常輸出。

通過上面一系列指令模擬發(fā)現(xiàn),(GPIO1、GPIO26)、(GPIO23、GPIO24)是綁定在一起的,調(diào)節(jié)任意一個,另外一個也會發(fā)生變化。也即是PWM0、PWM1雖然輸出了兩路,可以理解成兩路其實(shí)都是連在一個輸出口上。這里由于沒有示波器或者邏輯分析儀這類設(shè)備(僅有一個LED燈),所以測試很簡陋,下一步是使用示波器這類東西對頻率以及信號穩(wěn)定性進(jìn)行下測試。

小節(jié):樹莓派具有四路硬件輸出PWM能力,但是四路中只能輸出兩個獨(dú)立(占空比獨(dú)立)的PWM,同時四路輸出的頻率均是恒定的。

上面大概了解清楚了樹莓派3B的PWM結(jié)構(gòu),接下來就是探究如何使用Go語言進(jìn)行設(shè)置。

因為拿到了手冊,這里我想直接操作寄存器的方式進(jìn)行設(shè)置,也是順便學(xué)習(xí)下Go語言處理寄存器的過程。首先需要拿到pwm 系列寄存器的基地址,但是翻了一圈手冊,發(fā)現(xiàn)只有偏移,沒有找到基地址。

經(jīng)過了一段時間的努力后,決定寫一個 樹莓派3B golang包開源放在github上,只需要寫相關(guān)程序進(jìn)行調(diào)用就可以了,以下是相關(guān)demo(pwm)(在GPIO.12 上輸出PWM波,放上LED燈會有呼吸燈的效果,具體多少頻率還沒有進(jìn)行測試)

以下是demo(pwm) 源碼

go語言聊天室實(shí)現(xiàn)(二)gorilla/websocket中的聊天室示例

我們可以看到 gorilla/websocket中的examples中有一個聊天室的demo。

我們進(jìn)入該項目可以看到里面有這樣的一些內(nèi)容

按照官方的運(yùn)行方式來運(yùn)行這個項目

在瀏覽器中打開8080端口,可以看到該項目可以被成功運(yùn)行了。

就是這樣一個簡單的demo。

然后我們?nèi)タ匆幌滤木唧w實(shí)現(xiàn)。

在這個項目中首先定義了一個hub的結(jié)構(gòu)體:

這個結(jié)構(gòu)體中,clients代表所有已經(jīng)注冊的用戶,broadcast管道會存儲客戶端發(fā)送來的信息。 register是一個*Client類型的管道,用于存儲新注冊的用戶,unregister管道反之。

我們打開main.go,main函數(shù)的源碼為:

在這里首先會新開一個goroutine,去跑hub的run方法,run方法中一個死循環(huán),不停地去輪詢hub中的內(nèi)容

如果取到了新用戶,就加入到clients中,如果取到了信息,就循環(huán)所有的client,將信息寫到client.send中。

我們看到在請求路徑為根的時候,它會請求一個函數(shù),而這個函數(shù)就是將home.html發(fā)送到客戶端。

而在請求路徑為“/ws”的時候,他會執(zhí)行一個serveWS的函數(shù)。

每當(dāng)一個新的用戶進(jìn)來之后,首先將連接升級為長連接,然后將當(dāng)前的client寫到register中,由hub.run函數(shù)去做處理。然后開啟兩個goroutine,一個去讀client中發(fā)送來的數(shù)據(jù),一個將數(shù)據(jù)寫入到所有的client中,去發(fā)送給用戶。

這就是整個聊天室的實(shí)現(xiàn)原理。

一學(xué)就會,手把手教你用Go語言調(diào)用智能合約

智能合約調(diào)用是實(shí)現(xiàn)一個 DApp 的關(guān)鍵,一個完整的 DApp 包括前端、后端、智能合約及區(qū)塊 鏈系統(tǒng),智能合約的調(diào)用是連接區(qū)塊鏈與前后端的關(guān)鍵。

我們先來了解一下智能合約調(diào)用的基礎(chǔ)原理。智能合約運(yùn)行在以太坊節(jié)點(diǎn)的 EVM 中。因此要 想調(diào)用合約必須要訪問某個節(jié)點(diǎn)。

以后端程序為例,后端服務(wù)若想連接節(jié)點(diǎn)有兩種可能,一種是雙 方在同一主機(jī),此時后端連接節(jié)點(diǎn)可以采用 本地 IPC(Inter-Process Communication,進(jìn) 程間通信)機(jī)制,也可以采用 RPC(Remote Procedure Call,遠(yuǎn)程過程調(diào)用)機(jī)制;另 一種情況是雙方不在同一臺主機(jī),此時只能采用 RPC 機(jī)制進(jìn)行通信。

提到 RPC, 讀者應(yīng)該對 Geth 啟動參數(shù)有點(diǎn)印象,Geth 啟動時可以選擇開啟 RPC 服務(wù),對應(yīng)的 默認(rèn)服務(wù)端口是 8545。。

接著,我們來了解一下智能合約運(yùn)行的過程。

智能合約的運(yùn)行過程是后端服務(wù)連接某節(jié)點(diǎn),將 智能合約的調(diào)用(交易)發(fā)送給節(jié)點(diǎn),節(jié)點(diǎn)在驗證了交易的合法性后進(jìn)行全網(wǎng)廣播,被礦工打包到 區(qū)塊中代表此交易得到確認(rèn),至此交易才算完成。

就像數(shù)據(jù)庫一樣,每個區(qū)塊鏈平臺都會提供主流 開發(fā)語言的 SDK(Software Development Kit,軟件開發(fā)工具包),由于 Geth 本身就是用 Go 語言 編寫的,因此若想使用 Go 語言連接節(jié)點(diǎn)、發(fā)交易,直接在工程內(nèi)導(dǎo)入 go-ethereum(Geth 源碼) 包就可以了,剩下的問題就是流程和 API 的事情了。

總結(jié)一下,智能合約被調(diào)用的兩個關(guān)鍵點(diǎn)是節(jié)點(diǎn)和 SDK。

由于 IPC 要求后端與節(jié)點(diǎn)必須在同一主機(jī),所以很多時候開發(fā)者都會采用 RPC 模式。除了 RPC,以太坊也為開發(fā)者提供了 json- rpc 接口,本文就不展開討論了。

接下來介紹如何使用 Go 語言,借助 go-ethereum 源碼庫來實(shí)現(xiàn)智能合約的調(diào)用。這是有固定 步驟的,我們先來說一下總體步驟,以下面的合約為例。

步驟 01:編譯合約,獲取合約 ABI(Application Binary Interface,應(yīng)用二進(jìn)制接口)。 單擊【ABI】按鈕拷貝合約 ABI 信息,將其粘貼到文件 calldemo.abi 中(可使用 Go 語言IDE 創(chuàng)建該文件,文件名可自定義,后綴最好使用 abi)。

最好能將 calldemo.abi 單獨(dú)保存在一個目錄下,輸入“l(fā)s”命令只能看到 calldemo.abi 文件,參 考效果如下:

步驟 02:獲得合約地址。注意要將合約部署到 Geth 節(jié)點(diǎn)。因此 Environment 選擇為 Web3 Provider。

在【Environment】選項框中選擇“Web3 Provider”,然后單擊【Deploy】按鈕。

部署后,獲得合約地址為:0xa09209c28AEf59a4653b905792a9a910E78E7407。

步驟 03:利用 abigen 工具(Geth 工具包內(nèi)的可執(zhí)行程序)編譯智能合約為 Go 代碼。abigen 工具的作用是將 abi 文件轉(zhuǎn)換為 Go 代碼,命令如下:

其中各參數(shù)的含義如下。 (1)abi:是指定傳入的 abi 文件。 (2)type:是指定輸出文件中的基本結(jié)構(gòu)類型。 (3)pkg:指定輸出文件 package 名稱。 (4)out:指定輸出文件名。 執(zhí)行后,將在代碼目錄下看到 funcdemo.go 文件,讀者可以打開該文件欣賞一下,注意不要修改它。

步驟 04:創(chuàng)建 main.go,填入如下代碼。 注意代碼中 HexToAddress 函數(shù)內(nèi)要傳入該合約部署后的地址,此地址在步驟 01 中獲得。

步驟 04:設(shè)置 go mod,以便工程自動識別。

前面有所提及,若要使用 Go 語言調(diào)用智能合約,需要下載 go-ethereum 工程,可以使用下面 的指令:

該指令會自動將 go-ethereum 下載到“$GOPATH/src/github.com/ethereum/go-ethereum”,這樣還算 不錯。不過,Go 語言自 1.11 版本后,增加了 module 管理工程的模式。只要設(shè)置好了 go mod,下載 依賴工程的事情就不必關(guān)心了。

接下來設(shè)置 module 生效和 GOPROXY,命令如下:

在項目工程內(nèi),執(zhí)行初始化,calldemo 可以自定義名稱。

步驟 05:運(yùn)行代碼。執(zhí)行代碼,將看到下面的效果,以及最終輸出的 2020。

上述輸出信息中,可以看到 Go 語言會自動下載依賴文件,這就是 go mod 的神奇之處。看到 2020,相信讀者也知道運(yùn)行結(jié)果是正確的了。

php和go語言哪個好

前言

最近工作中遇到的一個場景,php項目中需要使用一個第三方的功能,而恰好有一個用Golang寫好的類庫。那么問題就來了,要如何實(shí)現(xiàn)不同語言之間的通信呢?下面就來一起看看吧。

常規(guī)的方案

1、 用Golang寫一個http/TCP服務(wù),php通過http/TCP與Golang通信

2、將Golang經(jīng)過較多封裝,做為php擴(kuò)展。

3、PHP通過系統(tǒng)命令,調(diào)取Golang的可執(zhí)行文件

存在的問題

1、http請求,網(wǎng)絡(luò)I/O將會消耗大量時間

2、需要封裝大量代碼

3、PHP每調(diào)取一次Golang程序,就需要一次初始化,時間消耗很多

優(yōu)化目標(biāo)

1、Golang程序只初始化一次(因為初始化很耗時)

2、所有請求不需要走網(wǎng)絡(luò)

3、盡量不大量修改代碼

解決方案

1、簡單的Golang封裝,將第三方類庫編譯生成為一個可執(zhí)行文件

2、PHP與Golang通過雙向管道通信

使用雙向管道通信優(yōu)勢

1:只需要對原有Golang類庫進(jìn)行很少的封裝

2:性能最佳 (IPC通信是進(jìn)程間通信的最佳途徑)

3:不需要走網(wǎng)絡(luò)請求,節(jié)約大量時間

4:程序只需初始化一次,并一直保持在內(nèi)存中

具體實(shí)現(xiàn)步驟

1:類庫中的原始調(diào)取demo

package main

import (

"fmt"

"github.com/yanyiwu/gojieba"

"strings"

)

func main() {

x := gojieba.NewJieba()

defer x.Free()

s := "小明碩士畢業(yè)于中國科學(xué)院計算所,后在日本京都大學(xué)深造"

words := x.CutForSearch(s, true)

fmt.Println(strings.Join(words, "/"))

}

保存文件為main.go,就可以運(yùn)行

2:調(diào)整后代碼為:

package main

import (

"bufio"

"fmt"

"github.com/yanyiwu/gojieba"

"io"

"os"

"strings"

)

func main() {

x := gojieba.NewJieba(

"/data/tmp/jiebaDict/jieba.dict.utf8",

"/data/tmp/jiebaDict/hmm_model.utf8",

"/data/tmp/jiebaDict/user.dict.utf8"

)

defer x.Free()

inputReader := bufio.NewReader(os.Stdin)

for {

s, err := inputReader.ReadString('\n')

if err != nil err == io.EOF {

break

}

s = strings.TrimSpace(s)

if s != "" {

words := x.CutForSearch(s, true)

fmt.Println(strings.Join(words, " "))

} else {

fmt.Println("get empty \n")

}

}

}

只需要簡單的幾行調(diào)整,即可實(shí)現(xiàn):從標(biāo)準(zhǔn)輸入接收字符串,經(jīng)過分詞再輸出

測試:

# go build test

# ./test

# //等待用戶輸入,輸入”這是一個測試“

# 這是 一個 測試 //程序

3:使用cat與Golang通信做簡單測試

//準(zhǔn)備一個title.txt,每行是一句文本

# cat title.txt | ./test

正常輸出,表示cat已經(jīng)可以和Golang正常交互了

4:PHP與Golang通信

以上所示的cat與Golang通信,使用的是單向管道。即:只能從cat向Golang傳入數(shù)據(jù),Golang輸出的數(shù)據(jù)并沒有傳回給cat,而是直接輸出到屏幕。但文中的需求是:php與Golang通信。即php要傳數(shù)據(jù)給Golang,同時Golang也必須把執(zhí)行結(jié)果返回給php。因此,需要引入雙向管道。

在PHP中管道的使用:popen("/path/test") ,具體就不展開說了,因為此方法解決不了文中的問題。

雙向管道:

$descriptorspec = array(

0 = array("pipe", "r"),

1 = array("pipe", "w")

);

$handle = proc_open(

'/webroot/go/src/test/test',

$descriptorspec,

$pipes

);

fwrite($pipes['0'], "這是一個測試文本\n");

echo fgets($pipes[1]);

解釋:使用proc_open打開一個進(jìn)程,調(diào)用Golang程序。同時返回一個雙向管道pipes數(shù)組,php向$pipe['0']中寫數(shù)據(jù),從$pipe['1']中讀數(shù)據(jù)。

好吧,也許你已經(jīng)發(fā)現(xiàn),我是標(biāo)題檔,這里重點(diǎn)要講的并不只是PHP與Golang如何通信。而是在介紹一種方法: 通過雙向管道讓任意語言通信。(所有語言都會實(shí)現(xiàn)管道相關(guān)內(nèi)容)

測試:

通過對比測試,計算出各個流程占用的時間。下面提到的title.txt文件,包含100萬行文本,每行文本是從b2b平臺取的商品標(biāo)題

1: 整體流程耗時

time cat title.txt | ./test /dev/null

耗時:14.819秒,消耗時間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù),將結(jié)果返回到屏幕

2:計算分詞函數(shù)耗時。方案:去除分詞函數(shù)的調(diào)取,即:注釋掉Golang源代碼中的調(diào)取分詞那行的代碼

time cat title.txt | ./test /dev/null

耗時:1.817秒時間,消耗時間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù),將結(jié)果返回到屏幕

分詞耗時 = (第一步耗時) - (以上命令所耗時)

分詞耗時 : 14.819 - 1.817 = 13.002秒

3:測試cat進(jìn)程與Golang進(jìn)程之間通信所占時間

time cat title.txt /dev/null

耗時:0.015秒,消耗時間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

go處理數(shù)據(jù),將結(jié)果返回到屏幕

管道通信耗時:(第二步耗時) - (第三步耗時)

管道通信耗時: 1.817 - 0.015 = 1.802秒

4:PHP與Golang通信的時間消耗

編寫簡單的php文件:

?php

$descriptorspec = array(

0 = array("pipe", "r"),

1 = array("pipe", "w")

);

$handle = proc_open(

'/webroot/go/src/test/test',

$descriptorspec,

$pipes

);

$fp = fopen("title.txt", "rb");

while (!feof($fp)) {

fwrite($pipes['0'], trim(fgets($fp))."\n");

echo fgets($pipes[1]);

}

fclose($pipes['0']);

fclose($pipes['1']);

proc_close($handle);

流程與上面基本一致,讀出title.txt內(nèi)容,通過雙向管道傳入Golang進(jìn)程分詞后,再返回給php (比上面的測試多一步:數(shù)據(jù)再通過管道返回)

time php popen.php /dev/null

耗時:24.037秒,消耗時間包含:

進(jìn)程PHP讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù)

Golang將返回結(jié)果再寫入管道,PHP通過管道接收數(shù)據(jù)

將結(jié)果返回到屏幕

結(jié)論:

1 :整個分詞過程中的耗時分布

使用cat控制邏輯耗時: 14.819 秒

使用PHP控制邏輯耗時: 24.037 秒(比cat多一次管道通信)

單向管道通信耗時: 1.8 秒

Golang中的分詞函數(shù)耗時: 13.002 秒

2:分詞函數(shù)的性能: 單進(jìn)程,100萬商品標(biāo)題分詞,耗時13秒

以上時間只包括分詞時間,不包括詞典載入時間。但在本方案中,詞典只載入一次,所以載入詞典時間可以忽略(1秒左右)

3:PHP比cat慢 (這結(jié)論有點(diǎn)多余了,呵呵)

語言層面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%

單進(jìn)程對比測試的話,應(yīng)該不會有哪個語言比cat更快。

相關(guān)問題:

1:以上Golang源碼中寫的是一個循環(huán),也就是會一直從管道中讀數(shù)據(jù)。那么存在一個問題:是不是php進(jìn)程結(jié)束后,Golang的進(jìn)程還會一直存在?

管道機(jī)制自身可解決此問題。管道提供兩個接口:讀、寫。當(dāng)寫進(jìn)程結(jié)束或者意外掛掉時,讀進(jìn)程也會報錯,以上Golang源代碼中的err邏輯就會執(zhí)行,Golang進(jìn)程結(jié)束。

但如果PHP進(jìn)程沒有結(jié)束,只是暫時沒有數(shù)據(jù)傳入,此時Golang進(jìn)程會一直等待。直到php結(jié)束后,Golang進(jìn)程才會自動結(jié)束。

2:能否多個php進(jìn)程并行讀寫同一個管道,Golang進(jìn)程同時為其服務(wù)?

不可以。管道是單向的,如果多個進(jìn)程同時向管道中寫,那Golang的返回值就會錯亂。

可以多開幾個Golang進(jìn)程實(shí)現(xiàn),每個php進(jìn)程對應(yīng)一個Golang進(jìn)程。

最后,上面都是瞎扯的。如果你了解管道、雙向管道,上面的解釋對你基本沒啥用。但如果你不了解管道,調(diào)試上面的代碼沒問題,但稍有修改就有可能掉坑里。

Go語言HTTPServer開發(fā)的六種實(shí)現(xiàn)

學(xué)完了 net/http 和 fasthttp 兩個HTTP協(xié)議接口的客戶端實(shí)現(xiàn),接下來就要開始Server的開發(fā),不學(xué)不知道一學(xué)嚇一跳,居然這兩個庫還支持Server的開發(fā),太方便了。

相比于Java的HTTPServer開發(fā)基本上都是使用Spring或者Springboot框架,總是要配置各種配置類,各種 handle 對象。Golang的Server開發(fā)顯得非常簡單,就是因為特別簡單,或者說沒有形成特別統(tǒng)一的規(guī)范或者框架,我發(fā)現(xiàn)了很多實(shí)現(xiàn)方式,HTTP協(xié)議基于還是 net/http 和 fasthttp ,但是 handle 語法就多種多樣了。

先復(fù)習(xí)一下: Golang語言HTTP客戶端實(shí)踐 、 Golang fasthttp實(shí)踐 。

在Golang語言方面,實(shí)現(xiàn)某個功能的庫可能會比較多,有機(jī)會還是要多跟同行交流,指不定就發(fā)現(xiàn)了更好用的庫。下面我分享我學(xué)到的六種Server開發(fā)的實(shí)現(xiàn)Demo。

基于 net/http 實(shí)現(xiàn),這是一種比較基礎(chǔ)的,對于接口和 handle 映射關(guān)系處理并不優(yōu)雅,不推薦使用。

第二種也是基于 net/http ,這種編寫語法可以很好地解決第一種的問題,handle和path有了類似配置的語法,可讀性提高了很多。

第三個基于 net/http 和 github.com/labstack/echo ,后者主要提供了 Echo 對象用來處理各類配置包括接口和handle映射,功能很豐富,可讀性最佳。

第四種依然基于 net/http 實(shí)現(xiàn),引入了 github.com/gin-gonic/gin 的路由,看起來接口和 handle 映射關(guān)系比較明晰了。

第五種基于 fasthttp 開發(fā),使用都是 fasthttp 提供的API,可讀性尚可,handle配置倒是更像Java了。

第六種依然基于 fasthttp ,用到了 github.com/buaazp/fasthttprouter ,有點(diǎn)奇怪兩個居然不在一個GitHub倉庫里。使用語法跟第三種方式有點(diǎn)類似,比較有條理,有利于閱讀。


標(biāo)題名稱:go語言h2demo Go語言并發(fā)
文章路徑:http://weahome.cn/article/hgpcdc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部