go語言進(jìn)程退出代碼 go語言錯(cuò)誤處理

Go語言基礎(chǔ)語法(一)

本文介紹一些Go語言的基礎(chǔ)語法。

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站與策劃設(shè)計(jì),石林網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:石林等地區(qū)。石林做網(wǎng)站價(jià)格咨詢:13518219792

先來看一個(gè)簡(jiǎn)單的go語言代碼:

go語言的注釋方法:

代碼執(zhí)行結(jié)果:

下面來進(jìn)一步介紹go的基礎(chǔ)語法。

go語言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),

常用方法:

示例代碼:

執(zhí)行結(jié)果:

更多格式化方法可以訪問中的fmt包。

log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。

執(zhí)行結(jié)果:

下面來介紹一下go的數(shù)據(jù)類型

下表列出了go語言的數(shù)據(jù)類型:

int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。

常量是在程序編譯時(shí)就確定下來的值,程序運(yùn)行時(shí)無法改變。

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

Go 語言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。

算術(shù)運(yùn)算符:

關(guān)系運(yùn)算符:

邏輯運(yùn)算符:

位運(yùn)算符:

賦值運(yùn)算符:

指針相關(guān)運(yùn)算符:

下面介紹一下go語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯(lián)用,這里不做介紹。

if語法格式如下:

if ... else :

else if:

示例代碼:

語法格式:

另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。

示例代碼:

執(zhí)行結(jié)果:

下面介紹幾種循環(huán)語句:

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

也可以通過標(biāo)記退出循環(huán):

--THE END--

golang減少switch

相比較 C 和 Java 等其它語言而言,Go 語言中的 switch 結(jié)構(gòu)使用上更加靈活。它接受任意形式的表達(dá)式,例如:

switch var1 {

case val1:

...

case val2:

...

default:

...

}

變量 var1 可以是任何類型,而 val1 和 val2 則可以是同類型的任意值。類型不被局限于常量或整數(shù),但必須是相同的類型;或者最終結(jié)果為相同類型的表達(dá)式。前花括號(hào){必須和 switch 關(guān)鍵字在同一行。 您可以同時(shí)測(cè)試多個(gè)可能符合條件的值,使用逗號(hào)分割它們,例如:case val1, val2, val3。每一個(gè) case 分支都是唯一的,從上至下逐一測(cè)試,直到匹配為止。一旦成功地匹配到每個(gè)分支,在執(zhí)行完相應(yīng)代碼后就會(huì)退出整個(gè) switch 代碼塊,也就是說你不需要特別使用 break 語句來表示結(jié)束。

Go語言里面switch默認(rèn)相當(dāng)于每個(gè)case最后帶有break,匹配成功后不會(huì)自動(dòng)向下執(zhí)行其他case,而是跳出整個(gè)switch。

應(yīng)用程序池 'DefaultAppPool' 被自動(dòng)禁用,原因是為此應(yīng)用程序池提供服務(wù)的進(jìn)程中出現(xiàn)一系列錯(cuò)誤。

為應(yīng)用程序池 'DefaultAppPool' 提供服務(wù)的進(jìn)程意外終止。進(jìn)程 ID 是 '3056'。進(jìn)程退出代碼是 '0xffffffff'。

有關(guān)更多信息,請(qǐng)參閱在 的幫助和支持中心。

-----------------------------------

解決方法,給NETWORK SERVICE 加上訪問iis服務(wù)的權(quán)限,具體方法如下:

-----------------------------------

點(diǎn)擊“開始”-“控制面板”-“管理工具”-“組件服務(wù)”-“計(jì)算機(jī)”-“我的電腦”-“DCOM”選項(xiàng),

選擇其下的“IIS ADMIN SERVICE”,右健選擇“屬性”,找到“安全”,在“啟動(dòng)和激活權(quán)限”中編輯“自定義”,添加帳號(hào)“NETWORK SERVICE ”,

給該帳號(hào)賦予“本地啟動(dòng)”和“本地激活”的權(quán)限,重新啟動(dòng)IIS(點(diǎn)“開始”-“運(yùn)行”-“CMD”,點(diǎn)確定,然后運(yùn)行IISRESET),

之后再訪問同一站點(diǎn),則一切正常。

另一解決方案:

事件類型: 警告

事件來源: W3SVC

事件種類: 無

事件 ID: 1009

日期: 2007-8-XX

事件: XX:XX:XX

用戶: XX

計(jì)算機(jī): XXXX

描述:

為應(yīng)用程序池 'XXXXX' 提供服務(wù)的進(jìn)程意外終止。進(jìn)程 ID 是 'XXXX'。進(jìn)程退出代碼是 '0x80'。

有關(guān)更多信息,請(qǐng)參閱在 的幫助和支持中心。

原因:

CAUSE

Together with each worker process that IIS creates under a separate identity, the system creates a new desktop object by allocating memory from the configured desktop heap. This issue occurs because, when that heap has been exhausted, IIS cannot create more worker processes. Clients then receive the "service unavailable" error message in their Web browsers when they try to visit Web sites that those application pools host.

獨(dú)立進(jìn)程的 內(nèi)存堆戔消耗完了,IIS不能創(chuàng)建更多的進(jìn)程工作空間來處理

解決方法:

警告:需要修改服務(wù)器的注冊(cè)表,請(qǐng)修改前備份相關(guān)鍵值

add the UseSharedWPDesktop registry key to your computer that is running IIS. This registry key permits all worker processes to run in one shared desktop, regardless of their worker process identities.

To add the UseSharedWPDesktop registry key:

1. HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC

2. 在Parameters鍵下新建一個(gè)DWORD項(xiàng),名字為:UseSharedWPDesktop 值為1 重啟IIS

MS關(guān)于此鍵值描述:

UseSharedWPDesktop

注冊(cè)表路徑:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters

數(shù)據(jù)類型:REG_DWORD

默認(rèn)值: 0

范圍: 0 - 1

如果您正使用唯一標(biāo)識(shí)設(shè)置應(yīng)用程序池,那么根據(jù)服務(wù)器上的應(yīng)用程序和內(nèi)存資源,將會(huì)達(dá)到大約 60 個(gè)應(yīng)用程序池的上限。某些分配了單個(gè)新登錄會(huì)話的系統(tǒng)資源存在一定的限制。這表明可以有 60 個(gè)進(jìn)程以不同的帳戶同時(shí)運(yùn)行。IIS 6.0 支持在單個(gè)共享的工作站和桌面中運(yùn)行這些進(jìn)程,所需的成本為在所有各方之間共享單個(gè)用戶會(huì)話的單個(gè)封裝。要擴(kuò)展到 60 個(gè)應(yīng)用程序池以上并共享單個(gè)桌面,可將 UseSharedWPDesktop 更改為 DWORD 值 1。更改此注冊(cè)表項(xiàng)之后,應(yīng)當(dāng)可以擴(kuò)展到上百個(gè)應(yīng)用程序池已及上百個(gè)同時(shí)運(yùn)行的工作進(jìn)程。

以上為轉(zhuǎn)載,是否恢復(fù)正常還需驗(yàn)證!

續(xù):經(jīng)過上面兩個(gè)方法后,系統(tǒng)日志還是出錯(cuò),都是說應(yīng)用池程序相關(guān)的進(jìn)程(與world wide web通信)致命錯(cuò)誤 ,突然在網(wǎng)上看到一句話,說要給system32的user權(quán)限(猜想可能要給system32\temp的權(quán)限,因?yàn)槭莇iscuz的NT版),給了之后,網(wǎng)站可以了,不過錯(cuò)誤還是會(huì)出現(xiàn),最終按上述的第一個(gè)辦法去解決,發(fā)現(xiàn)里面的netman的network service權(quán)限不見,添加之后,經(jīng)過幾小時(shí)的觀察,錯(cuò)誤沒有出來了

Golang 中更好的錯(cuò)誤處理:理論和實(shí)踐技巧

云和安全管理服務(wù)專家新鈦云服 張春翻譯

這種方法有幾個(gè)缺點(diǎn)。首先,它可以對(duì)程序員隱藏錯(cuò)誤處理路徑,特別是在捕獲異常不是強(qiáng)制性的情況下,例如在 Python 中。即使在具有必須處理的 Java 風(fēng)格的檢查異常的語言中,如果在與原始調(diào)用不同的級(jí)別上處理錯(cuò)誤,也并不總是很明顯錯(cuò)誤是從哪里引發(fā)的。

我們都見過長(zhǎng)長(zhǎng)的代碼塊包裝在一個(gè) try-catch 塊中。在這種情況下,catch 塊實(shí)際上充當(dāng) goto 語句,這通常被認(rèn)為是有害的(奇怪的是,C 中的關(guān)鍵字被認(rèn)為可以接受的少數(shù)用例之一是錯(cuò)誤后清理,因?yàn)樵撜Z言沒有 Golang- 樣式延遲語句)。

如果你確實(shí)從源頭捕獲異常,你會(huì)得到一個(gè)不太優(yōu)雅的 Go 錯(cuò)誤模式版本。這可能會(huì)解決混淆代碼的問題,但會(huì)遇到另一個(gè)問題:性能。在諸如 Java 之類的語言中,拋出異??赡鼙群瘮?shù)的常規(guī)返回慢數(shù)百倍。

Java 中最大的性能成本是由打印異常的堆棧跟蹤造成的,這是昂貴的,因?yàn)檫\(yùn)行的程序必須檢查編譯它的源代碼 。僅僅進(jìn)入一個(gè) try 塊也不是空閑的,因?yàn)樾枰4?CPU 內(nèi)存寄存器的先前狀態(tài),因?yàn)樗鼈兛赡苄枰趻伋霎惓5那闆r下恢復(fù)。

如果您將異常視為通常不會(huì)發(fā)生的異常情況,那么異常的缺點(diǎn)并不重要。這可能是傳統(tǒng)的單體應(yīng)用程序的情況,其中大部分代碼庫(kù)不必進(jìn)行網(wǎng)絡(luò)調(diào)用——一個(gè)操作格式良好的數(shù)據(jù)的函數(shù)不太可能遇到錯(cuò)誤(除了錯(cuò)誤的情況)。一旦您在代碼中添加 I/O,無錯(cuò)誤代碼的夢(mèng)想就會(huì)破滅:您可以忽略錯(cuò)誤,但不能假裝它們不存在!

try {

doSometing()

} catch (IOException e) {

// ignore it

}

與大多數(shù)其他編程語言不同,Golang 接受錯(cuò)誤是不可避免的。 如果在單體架構(gòu)時(shí)代還不是這樣,那么在今天的模塊化后端服務(wù)中,服務(wù)通常和外部 API 調(diào)用、數(shù)據(jù)庫(kù)讀取和寫入以及與其他服務(wù)通信 。

以上所有方法都可能失敗,解析或驗(yàn)證從它們接收到的數(shù)據(jù)(通常在無模式 JSON 中)也可能失敗。Golang 使可以從這些調(diào)用返回的錯(cuò)誤顯式化,與普通返回值的等級(jí)相同。從函數(shù)調(diào)用返回多個(gè)值的能力支持這一點(diǎn),這在大多數(shù)語言中通常是不可能的。Golang 的錯(cuò)誤處理系統(tǒng)不僅僅是一種語言怪癖,它是一種將錯(cuò)誤視為替代返回值的完全不同的方式!

重復(fù) if err != nil

對(duì) Go 錯(cuò)誤處理的一個(gè)常見批評(píng)是被迫重復(fù)以下代碼塊:

res, err := doSomething()

if err != nil {

// Handle error

}

對(duì)于新用戶來說,這可能會(huì)覺得沒用而且浪費(fèi)行數(shù):在其他語言中需要 3 行的函數(shù)很可能會(huì)增長(zhǎng)到 12 行 :

這么多行代碼!這么低效!如果您認(rèn)為上述內(nèi)容不優(yōu)雅或浪費(fèi)代碼,您可能忽略了我們檢查代碼中的錯(cuò)誤的全部原因:我們需要能夠以不同的方式處理它們!對(duì) API 或數(shù)據(jù)庫(kù)的調(diào)用可能會(huì)被重試。

有時(shí)事件的順序很重要:調(diào)用外部 API 之前發(fā)生的錯(cuò)誤可能不是什么大問題(因?yàn)閿?shù)據(jù)從未通過發(fā)送),而 API 調(diào)用和寫入本地?cái)?shù)據(jù)庫(kù)之間的錯(cuò)誤可能需要立即注意,因?yàn)?這可能意味著系統(tǒng)最終處于不一致的狀態(tài)。即使我們只想將錯(cuò)誤傳播給調(diào)用者,我們也可能希望用失敗的解釋來包裝它們,或者為每個(gè)錯(cuò)誤返回一個(gè)自定義錯(cuò)誤類型。

并非所有錯(cuò)誤都是相同的,并且向調(diào)用者返回適當(dāng)?shù)腻e(cuò)誤是 API 設(shè)計(jì)的重要部分,無論是對(duì)于內(nèi)部包還是 REST API 。

不必?fù)?dān)心在你的代碼中重復(fù) if err != nil ——這就是 Go 中的代碼應(yīng)該看起來的樣子。

自定義錯(cuò)誤類型和錯(cuò)誤包裝

從導(dǎo)出的方法返回錯(cuò)誤時(shí),請(qǐng)考慮指定自定義錯(cuò)誤類型,而不是單獨(dú)使用錯(cuò)誤字符串。字符串在意外代碼中是可以的,但在導(dǎo)出的函數(shù)中,它們成為函數(shù)公共 API 的一部分。更改錯(cuò)誤字符串將是一項(xiàng)重大更改——如果沒有明確的錯(cuò)誤類型,需要檢查返回錯(cuò)誤類型的單元測(cè)試將不得不依賴原始字符串值!事實(shí)上,基于字符串的錯(cuò)誤也使得在私有方法中測(cè)試不同的錯(cuò)誤案例變得困難,因此您也應(yīng)該考慮在包中使用它們。回到錯(cuò)誤與異常的爭(zhēng)論,返回錯(cuò)誤也使代碼比拋出異常更容易測(cè)試,因?yàn)殄e(cuò)誤只是要檢查的返回值。不需要測(cè)試框架或在測(cè)試中捕獲異常 。

可以在 database/sql 包中找到簡(jiǎn)單自定義錯(cuò)誤類型的一個(gè)很好的示例。它定義了一個(gè)導(dǎo)出常量列表,表示包可以返回的錯(cuò)誤類型,最著名的是 sql.ErrNoRows。雖然從 API 設(shè)計(jì)的角度來看,這種特定的錯(cuò)誤類型有點(diǎn)問題(您可能會(huì)爭(zhēng)辯說 API 應(yīng)該返回一個(gè)空結(jié)構(gòu)而不是錯(cuò)誤),但任何需要檢查空行的應(yīng)用程序都可以導(dǎo)入該常量并在代碼中使用它不必?fù)?dān)心錯(cuò)誤消息本身會(huì)改變和破壞代碼。

對(duì)于更復(fù)雜的錯(cuò)誤處理,您可以通過實(shí)現(xiàn)返回錯(cuò)誤字符串的 Error() 方法來定義自定義錯(cuò)誤類型。自定義錯(cuò)誤可以包括元數(shù)據(jù),例如錯(cuò)誤代碼或原始請(qǐng)求參數(shù)。如果您想表示錯(cuò)誤類別,它們很有用。DigitalOcean 的本教程展示了如何使用自定義錯(cuò)誤類型來表示可以重試的一類臨時(shí)錯(cuò)誤。

通常,錯(cuò)誤會(huì)通過將低級(jí)錯(cuò)誤與更高級(jí)別的解釋包裝起來,從而在程序的調(diào)用堆棧中傳播。例如,數(shù)據(jù)庫(kù)錯(cuò)誤可能會(huì)以下列格式記錄在 API 調(diào)用處理程序中:調(diào)用 CreateUser 端點(diǎn)時(shí)出錯(cuò):查詢數(shù)據(jù)庫(kù)時(shí)出錯(cuò):pq:檢測(cè)到死鎖。這很有用,因?yàn)樗梢詭椭覀兏欏e(cuò)誤在系統(tǒng)中傳播的過程,向我們展示根本原因(數(shù)據(jù)庫(kù)事務(wù)引擎中的死鎖)以及它對(duì)更廣泛系統(tǒng)的影響(調(diào)用者無法創(chuàng)建新用戶)。

自 Go 1.13 以來,此模式具有特殊的語言支持,并帶有錯(cuò)誤包裝。通過在創(chuàng)建字符串錯(cuò)誤時(shí)使用 %w 動(dòng)詞,可以使用 Unwrap() 方法訪問底層錯(cuò)誤。除了比較錯(cuò)誤相等性的函數(shù) errors.Is() 和 errors.As() 外,程序還可以獲取包裝錯(cuò)誤的原始類型或標(biāo)識(shí)。這在某些情況下可能很有用,盡管我認(rèn)為在確定如何處理所述錯(cuò)誤時(shí)最好使用頂級(jí)錯(cuò)誤的類型。

Panics

不要 panic()!長(zhǎng)時(shí)間運(yùn)行的應(yīng)用程序應(yīng)該優(yōu)雅地處理錯(cuò)誤而不是panic。即使在無法恢復(fù)的情況下(例如在啟動(dòng)時(shí)驗(yàn)證配置),最好記錄一個(gè)錯(cuò)誤并優(yōu)雅地退出。panic比錯(cuò)誤消息更難診斷,并且可能會(huì)跳過被推遲的重要關(guān)閉代碼。

Logging

我還想簡(jiǎn)要介紹一下日志記錄,因?yàn)樗翘幚礤e(cuò)誤的關(guān)鍵部分。通常你能做的最好的事情就是記錄收到的錯(cuò)誤并繼續(xù)下一個(gè)請(qǐng)求。

除非您正在構(gòu)建簡(jiǎn)單的命令行工具或個(gè)人項(xiàng)目,否則您的應(yīng)用程序應(yīng)該使用結(jié)構(gòu)化的日志庫(kù),該庫(kù)可以為日志添加時(shí)間戳,并提供對(duì)日志級(jí)別的控制。最后一部分特別重要,因?yàn)樗鼘⒃试S您突出顯示應(yīng)用程序記錄的所有錯(cuò)誤和警告。通過幫助將它們與信息級(jí)日志分開,這將為您節(jié)省無數(shù)時(shí)間。

微服務(wù)架構(gòu)還應(yīng)該在日志行中包含服務(wù)的名稱以及機(jī)器實(shí)例的名稱。默認(rèn)情況下記錄這些時(shí),程序代碼不必?fù)?dān)心包含它們。您也可以在日志的結(jié)構(gòu)化部分中記錄其他字段,例如收到的錯(cuò)誤(如果您不想將其嵌入日志消息本身)或有問題的請(qǐng)求或響應(yīng)。只需確保您的日志沒有泄露任何敏感數(shù)據(jù),例如密碼、API 密鑰或用戶的個(gè)人數(shù)據(jù)!

對(duì)于日志庫(kù),我過去使用過 logrus 和 zerolog,但您也可以選擇其他結(jié)構(gòu)化日志庫(kù)。如果您想了解更多信息,互聯(lián)網(wǎng)上有許多關(guān)于如何使用這些的指南。如果您將應(yīng)用程序部署到云中,您可能需要日志庫(kù)上的適配器來根據(jù)您的云平臺(tái)的日志 API 格式化日志 - 沒有它,云平臺(tái)可能無法檢測(cè)到日志級(jí)別等某些功能。

如果您在應(yīng)用程序中使用調(diào)試級(jí)別日志(默認(rèn)情況下通常不記錄),請(qǐng)確保您的應(yīng)用程序可以輕松更改日志級(jí)別,而無需更改代碼。更改日志級(jí)別還可以暫時(shí)使信息級(jí)別甚至警告級(jí)別的日志靜音,以防它們突然變得過于嘈雜并開始淹沒錯(cuò)誤。您可以使用在啟動(dòng)時(shí)檢查以設(shè)置日志級(jí)別的環(huán)境變量來實(shí)現(xiàn)這一點(diǎn)。

原文:

go語言--Goroutines

1、goroutine:在go語言中,每一個(gè)并發(fā)的執(zhí)行單元叫做goroutine,如果一個(gè)程序中包含多個(gè)goroutine,對(duì)兩個(gè)函數(shù)的調(diào)用則可能發(fā)生在同一時(shí)刻

2、main goroutine:當(dāng)一個(gè)程序啟動(dòng)時(shí),其主函數(shù)即在一個(gè)單獨(dú)的goroutine中運(yùn)行,我們叫他為main gorountine

3、go goroutine:新的goroutine會(huì)用go語句來創(chuàng)建,go+函數(shù)名,go語句會(huì)使其語句中的函數(shù)在一新創(chuàng)建的goroutine中運(yùn)行,而go語句本身會(huì)迅速地完成

4、goroutine的退出:主函數(shù)返回時(shí),所有的goroutine都會(huì)被直接打斷,程序退出,除了從主函數(shù)退出或者終止程序之外,沒有其他方法能夠讓一個(gè)goroutine來打斷另一個(gè)的執(zhí)行,但是可以通過另一種方式來實(shí)現(xiàn)這個(gè)目的,通過goroutine之間的通信來讓一個(gè)goroutine請(qǐng)求其他的goroutine,并讓請(qǐng)求的goroutine自行結(jié)束執(zhí)行

如何優(yōu)雅地等待所有的goroutine退出

goroutine和channel是Go語言非常棒的特色,它們提供了一種非常輕便易用的并發(fā)能力。但是當(dāng)您的應(yīng)用進(jìn)程中有很多goroutine的時(shí)候,如何在主流程中等待所有的goroutine 退出呢?

1 通過Channel傳遞退出信號(hào)

Go的一大設(shè)計(jì)哲學(xué)就是:通過Channel共享數(shù)據(jù),而不是通過共享內(nèi)存共享數(shù)據(jù)。主流程可以通過channel向任何goroutine發(fā)送停止信號(hào),就像下面這樣:

func run(done chan int) {

for {

select {

case -done:

fmt.Println("exiting...")

done - 1

break

default:

}

time.Sleep(time.Second * 1)

fmt.Println("do something")

}

}

func main() {

c := make(chan int)

go run(c)

fmt.Println("wait")

time.Sleep(time.Second * 5)

c - 1

-c

fmt.Println("main exited")

}

這種方式可以實(shí)現(xiàn)優(yōu)雅地停止goroutine,但是當(dāng)goroutine特別多的時(shí)候,這種方式不管在代碼美觀上還是管理上都顯得笨拙不堪。

2 使用waitgroup

sync包中的Waitgroup結(jié)構(gòu),是Go語言為我們提供的多個(gè)goroutine之間同步的好刀。下面是官方文檔對(duì)它的描述:

A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for.

Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.

通常情況下,我們像下面這樣使用waitgroup:

創(chuàng)建一個(gè)Waitgroup的實(shí)例,假設(shè)此處我們叫它wg

在每個(gè)goroutine啟動(dòng)的時(shí)候,調(diào)用wg.Add(1),這個(gè)操作可以在goroutine啟動(dòng)之前調(diào)用,也可以在goroutine里面調(diào)用。當(dāng)然,也可以在創(chuàng)建n個(gè)goroutine前調(diào)用wg.Add(n)

當(dāng)每個(gè)goroutine完成任務(wù)后,調(diào)用wg.Done()

在等待所有g(shù)oroutine的地方調(diào)用wg.Wait(),它在所有執(zhí)行了wg.Add(1)的goroutine都調(diào)用完wg.Done()前阻塞,當(dāng)所有g(shù)oroutine都調(diào)用完wg.Done()之后它會(huì)返回。

那么,如果我們的goroutine是一匹不知疲倦的牛,一直孜孜不倦地工作的話,如何在主流程中告知并等待它退出呢?像下面這樣做:

type Service struct {

// Other things

ch chan bool

waitGroup *sync.WaitGroup

}

func NewService() *Service {

s := Service{

// Init Other things

ch: make(chan bool),

waitGroup: sync.WaitGroup{},

}

return s

}

func (s *Service) Stop() {

close(s.ch)

s.waitGroup.Wait()

}

func (s *Service) Serve() {

s.waitGroup.Add(1)

defer s.waitGroup.Done()

for {

select {

case -s.ch:

fmt.Println("stopping...")

return

default:

}

s.waitGroup.Add(1)

go s.anotherServer()

}

}

func (s *Service) anotherServer() {

defer s.waitGroup.Done()

for {

select {

case -s.ch:

fmt.Println("stopping...")

return

default:

}

// Do something

}

}

func main() {

service := NewService()

go service.Serve()

// Handle SIGINT and SIGTERM.

ch := make(chan os.Signal)

signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)

fmt.Println(-ch)

// Stop the service gracefully.

service.Stop()

}

網(wǎng)站題目:go語言進(jìn)程退出代碼 go語言錯(cuò)誤處理
標(biāo)題鏈接:http://muchs.cn/article22/docdhjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器網(wǎng)站營(yíng)銷、響應(yīng)式網(wǎng)站企業(yè)建站、App設(shè)計(jì)網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)