golang環境變數,golang 環境

本文目錄一覽:

golang 進程創建,fork,以及熱重啟(無縫升級)

一般來說,進程的操作使用的是一些系統的命令,所以go內部使用os包,進行一些運行系統命令的操作

os 包及其子包 os/exec 提供了創建進程的方法。

一般的,應該優先使用 os/exec 包。因為 os/exec 包依賴 os 包中關鍵創建進程的 API,為了便於理解,我們先探討 os 包中和進程相關的部分。

Unix :fork創建一個進程,(及其一些變種,如 vfork、clone)。

Go:Linux 下創建進程使用的系統調用是 clone。

允許一進程(父進程)創建一新進程(子進程)。具體做法是,新的子進程幾近於對父進程的翻版:子進程獲得父進程的棧、數據段、堆和執行文本段的拷貝。可將此視為把父進程一分為二。

終止一進程,將進程佔用的所有資源(內存、文件描述符等)歸還內核,交其進行再次分配。參數 status 為一整型變數,表示進程的退出狀態。父進程可使用系統調用 wait() 來獲取該狀態。

目的有二:其一,如果子進程尚未調用 exit() 終止,那麼 wait 會掛起父進程直至子進程終止;其二,子進程的終止狀態通過 wait 的 status 參數返回。

載入一個新程序(路徑名為 pathname,參數列表為 argv,環境變數列表為 envp)到當前進程的內存。這將丟棄現存的程序文本段,並為新程序重新創建棧、數據段以及堆。通常將這一動作稱為執行一個新程序。

沒有直接提供 fork 系統調用的封裝,而是將 fork 和 execve 合二為一,提供了 syscall.ForkExec。如果想只調用 fork,得自己通過 syscall.Syscall(syscall.SYS_FORK, 0, 0, 0) 實現。

os.Process 存儲了通過 StartProcess 創建的進程的相關信息。

一般通過 StartProcess 創建 Process 的實例,函數聲明如下:

它使用提供的程序名、命令行參數、屬性開始一個新進程。StartProcess 是一個低級別的介面。os/exec 包提供了高級別的介面,一般應該盡量使用 os/exec 包。如果出錯,錯誤的類型會是 *PathError。

屬性定義如下:

FindProcess 可以通過 pid 查找一個運行中的進程。該函數返回的 Process 對象可以用於獲取關於底層操作系統進程的信息。在 Unix 系統中,此函數總是成功,即使 pid 對應的進程不存在。

Process 提供了四個方法:Kill、Signal、Wait 和 Release。其中 Kill 和 Signal 跟信號相關,而 Kill 實際上就是調用 Signal,發送了 SIGKILL 信號,強制進程退出,關於信號,後續章節會專門講解。

Release 方法用於釋放 Process 對象相關的資源,以便將來可以被再使用。該方法只有在確定沒有調用 Wait 時才需要調用。Unix 中,該方法的內部實現只是將 Process 的 pid 置為 -1。

通過 os 包可以做到運行外部命令,如前面的例子。不過,Go 標準庫為我們封裝了更好用的包: os/exec,運行外部命令,應該優先使用它,它包裝了 os.StartProcess 函數以便更容易的重定向標準輸入和輸出,使用管道連接 I/O,以及作其它的一些調整。

exec.LookPath 函數在 PATH 指定目錄中搜索可執行程序,如 file 中有 /,則只在當前目錄搜索。該函數返回完整路徑或相對於當前路徑的一個相對路徑。

func LookPath(file string) (string, error)

如果在 PATH 中沒有找到可執行文件,則返回 exec.ErrNotFound。

Cmd 結構代表一個正在準備或者在執行中的外部命令,調用了 Run、Output 或 CombinedOutput 後,Cmd 實例不能被重用。

一般的,應該通過 exec.Command 函數產生 Cmd 實例:

用法

得到 * Cmd 實例後,接下來一般有兩種寫法:

前面講到,通過 Cmd 實例後,有兩種方式運行命令。有時候,我們不只是簡單的運行命令,還希望能控制命令的輸入和輸出。通過上面的 API 介紹,控制輸入輸出有幾種方法:

參考資料:

golang伺服器比測視機慢

解決辦法:①關閉殺毒軟體 (首先嘗試)。②設置 gopoxy代理。

具體的設置如下:設置環境變數: 變數名GOPROXY,變數值:關閉 vscode 之後,重新打開程序,然後運行。如果還是很慢,連結果都不出的話,重新檢查程序,看看程序的循環是不是有問題,或者是程序本身就沒有輸出。

Golang入門到項目實戰 | golang簡介及安裝

Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開發的一種靜態強類型、編譯型語言。Go 語言語法與 C 相近,但功能上有:內存安全,GC(垃圾回收),結構形態及 CSP-style 並發計算。

go語言特點

go語言的應用領域

哪些公司(項目)在使用go語言

下載開發包

windows下安裝

1.打開下載的msi可執行文件,根據提示進行安裝。默認會安裝在c:/Program Files/go目錄下面。會自動添加go可執行文件環境變數。

2.驗證安裝情況

a.打開命令行

b. 輸入$ go version

linux下安裝

1.在/usr/local/下面創建一個目錄go

2.下載壓縮文件到該目錄(/usr/local/go),並解壓縮

3.添加/usr/local/go/bin到PATH環境變數,打開$HOME/.profile 或者/etc/profile輸入如下內容:

4.執行如下命令使得配置文件及時生效

驗證

1.如果你的mac有Homebrew包管理工具,可以使用它來安裝

2.如果沒有下載mac安裝包,根據提示安裝

3.默認安裝在/usr/local/go下面

4.設置環境變數,同Linux

Golang 的靜態編譯

Go 語言和 C 語言的一個很大的區別是, Go 語言只靜態編譯,做個測試:

一方面是 Go 語言編譯後的可執行文件大小比 C 語言的大很多,

另一方面是 C 語言的可執行文件需要依賴 glibc 動態庫,

用 ldd 命令可以看出來:

或者直接刪除 glibc 動態庫, C 可執行程序報錯,而 Go 的還能運行:

這時候只有內部命令可以運行,外部命令,包括 ln 甚至最常用的 ls 命令也不能運行了:

設置好 LD_PRELOAD 環境變數之後, ln 命令可以運行,但是 sudo 仍然不能運行

只能靠 root 用戶來重新創建軟連接了:

所以用 sudo 來 rm 文件要小心,還是用 root 比較好。如果沒有預先留一個打開的 root 終端,登錄都登不進去。

Golang實驗性功能SetMaxHeap 固定值GC

簡單來說, SetMaxHeap 提供了一種可以設置固定觸發閾值的 GC (Garbage Collection垃圾回收)方式

官方源碼鏈接

大量臨時對象分配導致的 GC 觸發頻率過高, GC 後實際存活的對象較少,

或者機器內存較充足,希望使用剩餘內存,降低 GC 頻率的場景

GC 會 STW ( Stop The World ),對於時延敏感場景,在一個周期內連續觸發兩輪 GC ,那麼 STW 和 GC 佔用的 CPU 資源都會造成很大的影響, SetMaxHeap 並不一定是完美的,在某些場景下做了些權衡,官方也在進行相關的實驗,當前方案仍沒有合入主版本。

先看下如果沒有 SetMaxHeap ,對於如上所述的場景的解決方案

這裡簡單說下 GC 的幾個值的含義,可通過 GODEBUG=gctrace=1 獲得如下數據

這裡只關注 128-132-67 MB 135 MB goal ,

分別為 GC開始時內存使用量 – GC標記完成時內存使用量 – GC標記完成時的存活內存量 本輪GC標記完成時的 預期 內存使用量(上一輪 GC 完成時確定)

引用 GC peace設計文檔 中的一張圖來說明

對應關係如下:

簡單說下 GC pacing (信用機制)

GC pacing 有兩個目標,

那麼當一輪 GC 完成時,如何只根據本輪 GC 存活量去實現這兩個小目標呢?

這裡實際是根據當前的一些數據或狀態去 預估 「未來」,所有會存在些誤差

首先確定 gc Goal goal = memstats.heap_marked + memstats.heap_marked*uint64(gcpercent)/100

heap_marked 為本輪 GC 存活量, gcpercent 默認為 100 ,可以通過環境變數 GOGC=100 或者 debug.SetGCPercent(100) 來設置

那麼默認情況下 goal = 2 * heap_marked

gc_trigger 是與 goal 相關的一個值( gc_trigger 大約為 goal 的 90% 左右),每輪 GC 標記完成時,會根據 |Ha-Hg| 和實際使用的 cpu 資源 動態調整 gc_trigger 與 goal 的差值

goal 與 gc_trigger 的差值即為,為 GC 期間分配的對象所預留的空間

GC pacing 還會預估下一輪 GC 發生時,需要掃描對象對象的總量,進而換算為下一輪 GC 所需的工作量,進而計算出 mark assist 的值

本輪 GC 觸發( gc_trigger ),到本輪的 goal 期間,需要儘力完成 GC mark 標記操作,所以當 GC 期間,某個 goroutine 分配大量內存時,就會被拉去做 mark assist 工作,先進行 GC mark 標記賺取足夠的信用值後,才能分配對應大小的對象

根據本輪 GC 存活的內存量( heap_marked )和下一輪 GC 觸發的閾值( gc_trigger )計算 sweep assist 的值,本輪 GC 完成,到下一輪 GC 觸發( gc_trigger )時,需要儘力完成 sweep 清掃操作

預估下一輪 GC 所需的工作量的方式如下:

繼續分析文章開頭的問題,如何充分利用剩餘內存,降低 GC 頻率和 GC 對 CPU 的資源消耗

如上圖可以看出, GC 後,存活的對象為 2GB 左右,如果將 gcpercent 設置為 400 ,那麼就可以將下一輪 GC 觸發閾值提升到 10GB 左右

前面一輪看起來很好,提升了 GC 觸發的閾值到 10GB ,但是如果某一輪 GC 後的存活對象到達 2.5GB 的時候,那麼下一輪 GC 觸發的閾值,將會超過內存閾值,造成 OOM ( Out of Memory ),進而導致程序崩潰。

可以通過 GOGC=off 或者 debug.SetGCPercent(-1) 來關閉 GC

可以通過進程外監控內存使用狀態,使用信號觸發的方式通知程序,或 ReadMemStats 、或 linkname runtime.heapRetained 等方式進行堆內存使用的監測

可以通過調用 runtime.GC() 或者 debug.FreeOSMemory() 來手動進行 GC 。

這裡還需要說幾個事情來解釋這個方案所存在的問題

通過 GOGC=off 或者 debug.SetGCPercent(-1) 是如何關閉 GC 的?

gc 4 @1.006s 0%: 0.033+5.6+0.024 ms clock, 0.27+4.4/11/25+0.19 ms cpu, 428-428-16 MB, 17592186044415 MB goal, 8 P (forced)

通過 GC trace 可以看出,上面所說的 goal 變成了一個很詭異的值 17592186044415

實際上關閉 GC 後, Go 會將 goal 設置為一個極大值 ^uint64(0) ,那麼對應的 GC 觸發閾值也被調成了一個極大值,這種處理方式看起來也沒什麼問題,將閾值調大,預期永遠不會再觸發 GC

那麼如果在關閉 GC 的情況下,手動調用 runtime.GC() 會導致什麼呢?

由於 goal 和 gc_trigger 被設置成了極大值, mark assist 和 sweep assist 也會按照這個錯誤的值去計算,導致工作量預估錯誤,這一點可以從 trace 中進行證明

可以看到很詭異的 trace 圖,這裡不做深究,該方案與 GC pacing 信用機制不兼容

記住,不要在關閉 GC 的情況下手動觸發 GC ,至少在當前 Go1.14 版本中仍存在這個問題

SetMaxHeap 的實現原理,簡單來說是強行控制了 goal 的值

註: SetMaxHeap ,本質上是一個軟限制,並不能解決 極端場景 下的 OOM ,可以配合內存監控和 debug.FreeOSMemory() 使用

SetMaxHeap 控制的是堆內存大小, Go 中除了堆內存還分配了如下內存,所以實際使用過程中,與實際硬體內存閾值之間需要留有一部分餘量。

對於文章開始所述問題,使用 SetMaxHeap 後,預期的 GC 過程大概是這個樣子

簡單用法1

該方法簡單粗暴,直接將 goal 設置為了固定值

註:通過上文所講,觸發 GC 實際上是 gc_trigger ,所以當閾值設置為 12GB 時,會提前一點觸發 GC ,這裡為了描述方便,近似認為 gc_trigger=goal

簡單用法2

當不關閉 GC 時, SetMaxHeap 的邏輯是, goal 仍按照 gcpercent 進行計算,當 goal 小於 SetMaxHeap 閾值時不進行處理;當 goal 大於 SetMaxHeap 閾值時,將 goal 限制為 SetMaxHeap 閾值

註:通過上文所講,觸發 GC 實際上是 gc_trigger ,所以當閾值設置為 12GB 時,會提前一點觸發 GC ,這裡為了描述方便,近似認為 gc_trigger=goal

切換到 go1.14 分支,作者選擇了 git checkout go1.14.5

選擇官方提供的 cherry-pick 方式(可能需要梯子,文件改動不多,我後面會列出具體改動)

git fetch “” refs/changes/67/227767/3 git cherry-pick FETCH_HEAD

需要重新編譯Go源碼

注意點:

下面源碼中的官方注釋說的比較清楚,在一些關鍵位置加入了中文注釋

入參bytes為要設置的閾值

notify 簡單理解為 GC 的策略 發生變化時會向 channel 發送通知,後續源碼可以看出「策略」具體指哪些內容

返回值為本次設置之前的 MaxHeap 值

$GOROOT/src/runtime/debug/garbage.go

$GOROOT/src/runtime/mgc.go

註:作者盡量用通俗易懂的語言去解釋 Go 的一些機制和 SetMaxHeap 功能,可能有些描述與實現細節不完全一致,如有錯誤還請指出

如何配置go語言開發環境

1、下載go的zip文件。並且一定要把文件解壓到c:\go目錄下。

2、配置windows的高級環境變數。包括:GOROOT、GOOS、GOBIN、GOARCH。並且在path變數裡面把c:\go\bin加入。以便可以在命令行直接運行go命令。

舉例:我的機器:

GOPATH= c:\go;c:\go\src;F:\workspace\goSample01;

GOBIN=c:\go\bin;F:\workspace\goSample01\bin;

其中,c:\go是go的安裝路徑;

F:\workspace\goSample01是我寫的go語言項目的工程目錄;

F:\workspace\goSample01\bin是go語言項目的工程目錄下的可執行文件路徑;

3、在完成環境變數配置後,打開一個命令行窗口,直接輸入go,然後回車,看看是否出現go的幫助信息。如果出現,那麼go的基本環境就OK了。

注意:這個基本環境不包含開發工具,也不能直接編譯帶C代碼的go程序。

4、

(可選)為了支持Import遠程包,最好裝個gomingw。下載地址:

/downloads/list。如果下的是壓縮包,請把它解壓到C盤。例如,C:\gowin-env。裡面有個Console.bat是以後使用go

get的環境。舉例:有個文件a.go,裡面import(

“fmt”

“github.com/astaxie/beedb”

_ “github.com/ziutek/mymysql/godrv”

為了編譯該a.go文件,需要啟動Console.bat,然後在該命令行窗口,進入c:\go\src目錄下,執行go getgithub.com/astaxie/beedb

Go get github.com/ziutek/mymysql/godrv .

Go會自動下載該遠程包並編譯和安裝這些包。

配置goclipse(可選)

(如果不喜歡eclipse開發工具,請跳過這個配置。)

1、下載並安裝goclipse插件。Goclipse是go語言for eclipse的插件,下載地址:

2、啟動eclipse並創建go項目。然後寫個最簡單的helloworld.go文件,並運行。代碼如下:

packagemainimport”fmt”func main(){ fmt.Printf(“hello, world”)}

配置gocode(可選)

如果不需要go語法輔助和eclipse裡面的(按ALT+/)彈出go語言自動輔助功能,請跳過這個配置。

1、下載gocode的zip文件,解壓後放在go的bin目錄下。

2、下載並安裝Git軟體。並且在path裡面配置git的執行路徑。例如c:\git\bin

3、在命令行執行:go build .\gocode。如果一切正常,那麼將會編譯生成一個gocode.exe文件在go的bin目錄下。如果編譯失敗,那麼就轉第4步。

4、如果第3步直接編譯gocode源文件成功,那就直接到第5步。否則,就需要通過git下載gocode源文件,然後再編譯。在命令行執行:go get -u github.com/nsf/gocode 。就會生成gocode.exe文件。

5、在goclipse插件裡面指定gocode的路徑。就可以在elcipse裡面調用gocode來幫助寫編碼了。

從開發工具這塊看,go語言還不夠成熟,開發工具都還不完善,有待改進。

下載go-tour教程源代碼(可選)

Google有個在線運行go語言的教程(),很不錯。支持在web上直接運行大部分的go程序,想了解這個教程的源代碼的朋友可以通過以下方式獲取。如果沒興趣,可以跳過這個步驟。

1、下載安裝Mercurial軟體。

2、在命令行下輸入:

hg clone

作為測試用的。如果把http改成https協議,下載就會失敗。搞不懂。

編譯帶調用C代碼的go文件(可選)

1、為了在windows下編譯帶C代碼的go程序,你首先需要下載並安裝MinGW或者Cygwin。

2、首選安裝MinGW。在安裝MinGW之後,記得要把MinGW安裝目錄\bin路徑設置在path環境變數裡面,以便能在dos窗口下直接調用gcc。

3、下載一個gowin-env。下載地址:gowin-env。下載後解壓到某個目錄下,例如:C:\gowin-env. 然後,編輯go-env.bat。配置相關的go參數。例如,我的配置是:

set GOARCH=386

set GOOS=windows

set GOROOT=c:\go

set GOBIN=%GOROOT%\bin

set GOPATH=%GOROOT%;F:\workspace\goSample01;

設置好go-env.bat後,就可以點擊Console.bat來啟動編譯和運行窗口。

4、編寫一個帶C代碼的go程序。例如,testc.go

5、編譯

例如:

go build -compiler gccgo test_c.go

運行調用C代碼的go文件(可選)

1、testc.go.

創建rand目錄,然後在rand裡面創建testc.go. 代碼如下:

package rand

/*

//

#include stdio.h

*/

import “C”

func PrintHello() {

C.puts(C.CString(“Hello, world\n”))

}

2、a.go

在rand下創建a.go.代碼如下:

package rand

import “fmt”

func SayHello(name string){

fmt.Println(name)

}

3、test_import.go

在rand的上一級創建test_import.go。代碼如下:

package main

import “./rand”

func main(){

rand.SayHello(“tom”)

rand.PrintHello()

}

4、運行test_import.go

go run test_import.go

在測試其它幾個C代碼的時候,發現windows版本的cgo還有些編譯問題,同樣的代碼轉移到蘋果的XCODE下就沒有問題。後來終於發現原因了,原來有些例子是unix平台下的,而在windows平台下,方法名和參數需要做調整。

例如:下面代碼在windows下編譯報一堆錯誤。

package rand

/*

#include stdlib.h

*/

import “C”

func Random() int {

return int(C.random())

}

func Seed(i int) {

C.srandom(C.uint(i))

}

這裡需要把return int(C.random()) 修改為「return int(C.rand())」

C.srandom(C.uint(i))修改為「C.srand(C.uint(i))」編譯就OK了。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/279873.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-20 15:05
下一篇 2024-12-20 15:05

相關推薦

  • 如何設置Python環境變數

    Python是一種流行的腳本編程語言,它可以在不同的操作系統和平台上運行。但是,在使用Python時,我們需要設置Python環境變數,以便系統能夠正確地找到Python解釋器和相…

    編程 2025-04-29
  • 使用Golang調用Python

    在現代軟體開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29
  • 如何部署一個服務到一個環境

    本文將從多個方面對如何部署一個服務到一個環境進行詳細的闡述,包括環境準備、代碼編寫、打包部署等。 一、環境準備 1、確定部署環境的操作系統版本、運行時環境(如JDK、Node.js…

    編程 2025-04-29
  • Python開發環境包括

    Python作為一門高效、易讀易學的語言,已經被越來越多的開發者使用。而Python的開發環境也發展得越來越完善。本文將會從以下幾個方面對Python開發環境包括做詳細的闡述: 一…

    編程 2025-04-29
  • 如何配置Python環境變數在Windows 11

    在本文中,您將學習如何在Windows 11操作系統上配置Python環境變數的步驟。Python是一種高級編程語言,廣泛用於編寫Web應用程序、數據分析、人工智慧和機器學習等。在…

    編程 2025-04-29
  • 內核驅動編譯環境代價分析

    內核驅動編譯環境是在Linux系統中編譯內核模塊的過程。本文通過分析內核驅動編譯環境的各個方面,包括編譯工具的選擇、編譯速度、編譯器選項等,來探討其代價所在,並提供一些優化的建議。…

    編程 2025-04-29
  • 使用Golang創建黑色背景圖片的方法

    本文將從多個方面介紹使用Golang創建黑色背景圖片的方法。 一、安裝必要的代碼庫和工具 在開始創建黑色背景圖片之前,我們需要先安裝必要的代碼庫和工具: go get -u git…

    編程 2025-04-29
  • 如何使用cmd激活python虛擬環境

    Python虛擬環境是Python用來隔離項目所需包和依賴庫的工具,以免不同項目之間的依賴關係衝突。下面將從安裝虛擬環境、創建虛擬環境、激活虛擬環境這3個方面來詳細講解如何在cmd…

    編程 2025-04-28
  • Apache配置Python環境

    Apache是一款流行的Web伺服器軟體,事實上,很多時候我們需要在Web伺服器上使用Python程序做為數據處理和前端網頁開發語言,這時候,我們就需要在Apache中配置Pyth…

    編程 2025-04-28
  • Ubuntu系統激活Python環境

    本文將從以下幾個方面詳細介紹在Ubuntu系統中如何激活Python環境: 一、安裝Python 在Ubuntu系統中默認已經預裝了Python解釋器,可以通過以下命令來檢查: $…

    編程 2025-04-28

發表回復

登錄後才能評論