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

成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)由有經(jīng)驗(yàn)的網(wǎng)站設(shè)計(jì)師、開(kāi)發(fā)人員和項(xiàng)目經(jīng)理組成的專業(yè)建站團(tuán)隊(duì),負(fù)責(zé)網(wǎng)站視覺(jué)設(shè)計(jì)、用戶體驗(yàn)優(yōu)化、交互設(shè)計(jì)和前端開(kāi)發(fā)等方面的工作,以確保網(wǎng)站外觀精美、成都做網(wǎng)站、網(wǎng)站制作易于使用并且具有良好的響應(yīng)性。
2、main goroutine:當(dāng)一個(gè)程序啟動(dòng)時(shí),其主函數(shù)即在一個(gè)單獨(dú)的goroutine中運(yùn)行,我們叫他為main gorountine
3、go goroutine:新的goroutine會(huì)用go語(yǔ)句來(lái)創(chuàng)建,go+函數(shù)名,go語(yǔ)句會(huì)使其語(yǔ)句中的函數(shù)在一新創(chuàng)建的goroutine中運(yùn)行,而go語(yǔ)句本身會(huì)迅速地完成
4、goroutine的退出:主函數(shù)返回時(shí),所有的goroutine都會(huì)被直接打斷,程序退出,除了從主函數(shù)退出或者終止程序之外,沒(méi)有其他方法能夠讓一個(gè)goroutine來(lái)打斷另一個(gè)的執(zhí)行,但是可以通過(guò)另一種方式來(lái)實(shí)現(xiàn)這個(gè)目的,通過(guò)goroutine之間的通信來(lái)讓一個(gè)goroutine請(qǐng)求其他的goroutine,并讓請(qǐng)求的goroutine自行結(jié)束執(zhí)行
func?startTimer(f?func())?{
go?func()?{
for?{
f()
now?:=?time.Now()
//?計(jì)算下一個(gè)零點(diǎn)
next?:=?now.Add(time.Hour?*?24)
next?=?time.Date(next.Year(),?next.Month(),?next.Day(),?0,?0,?0,?0,?next.Location())
t?:=?time.NewTimer(next.Sub(now))
-t.C
}
}()
}
在linux下實(shí)現(xiàn)定時(shí)器主要有如下方式
在這當(dāng)中 基于時(shí)間輪方式實(shí)現(xiàn)的定時(shí)器 時(shí)間復(fù)雜度最小,效率最高,然而我們可以通過(guò) 優(yōu)先隊(duì)列 實(shí)現(xiàn)時(shí)間輪定時(shí)器。
優(yōu)先隊(duì)列的實(shí)現(xiàn)可以使用最大堆和最小堆,因此在隊(duì)列中所有的數(shù)據(jù)都可以定義排序規(guī)則自動(dòng)排序。我們直接通過(guò)隊(duì)列中 pop 函數(shù)獲取數(shù)據(jù),就是我們按照自定義排序規(guī)則想要的數(shù)據(jù)。
在 Golang 中實(shí)現(xiàn)一個(gè)優(yōu)先隊(duì)列異常簡(jiǎn)單,在 container/head 包中已經(jīng)幫我們封裝了,實(shí)現(xiàn)的細(xì)節(jié),我們只需要實(shí)現(xiàn)特定的接口就可以。
下面是官方提供的例子
因?yàn)閮?yōu)先隊(duì)列底層數(shù)據(jù)結(jié)構(gòu)是由二叉樹(shù)構(gòu)建的,所以我們可以通過(guò)數(shù)組來(lái)保存二叉樹(shù)上的每一個(gè)節(jié)點(diǎn)。
改數(shù)組需要實(shí)現(xiàn) Go 預(yù)先定義的接口 Len , Less , Swap , Push , Pop 和 update 。
timerType結(jié)構(gòu)是定時(shí)任務(wù)抽象結(jié)構(gòu)
首先的 start 函數(shù),當(dāng)創(chuàng)建一個(gè) TimeingWheel 時(shí),通過(guò)一個(gè) goroutine 來(lái)執(zhí)行 start ,在start中for循環(huán)和select來(lái)監(jiān)控不同的channel的狀態(tài)
通過(guò)for循環(huán)從隊(duì)列中取數(shù)據(jù),直到該隊(duì)列為空或者是遇見(jiàn)第一個(gè)當(dāng)前時(shí)間比任務(wù)開(kāi)始時(shí)間大的任務(wù), append 到 expired 中。因?yàn)閮?yōu)先隊(duì)列中是根據(jù) expiration 來(lái)排序的,
所以當(dāng)取到第一個(gè)定時(shí)任務(wù)未到的任務(wù)時(shí),表示該定時(shí)任務(wù)以后的任務(wù)都未到時(shí)間。
當(dāng) getExpired 函數(shù)取出隊(duì)列中要執(zhí)行的任務(wù)時(shí),當(dāng)有的定時(shí)任務(wù)需要不斷執(zhí)行,所以就需要判斷是否該定時(shí)任務(wù)需要重新放回優(yōu)先隊(duì)列中。 isRepeat 是通過(guò)判斷任務(wù)中 interval 是否大于 0 判斷,
如果大于0 則,表示永久就生效。
防止外部濫用,阻塞定時(shí)器協(xié)程,框架又一次封裝了timer這個(gè)包,名為 timer_wapper 這個(gè)包,它提供了兩種調(diào)用方式。
參數(shù)和上面的參數(shù)一樣,只是在第三個(gè)參數(shù)中使用了任務(wù)池,將定時(shí)任務(wù)放入了任務(wù)池中。定時(shí)任務(wù)的本身執(zhí)行就是一個(gè) put 操作。
至于put以后,那就是 workers 這個(gè)包管理的了。在 worker 包中, 也就是維護(hù)了一個(gè)任務(wù)池,任務(wù)池中的任務(wù)會(huì)有序的執(zhí)行,方便管理。
簡(jiǎn)單學(xué)習(xí)了golang/go語(yǔ)言的基礎(chǔ)語(yǔ)法,做個(gè)定時(shí)切割nginx日志的小腳本練習(xí)下,感覺(jué)挺好使的~
腳本代碼如下,install后將腳本加入到crontab定時(shí)運(yùn)行,當(dāng)然golang也可以自己定時(shí)執(zhí)行,這里加入到crontab運(yùn)行,是因?yàn)間olang進(jìn)程有可能會(huì)被kill掉....
package main
import (
"fmt"
"os"
"path/filepath"
"syscall"
"time"
"strings"
"os/exec"
"io/ioutil"
)
func main(){
//日志目錄
srcDirPath := "/usr/local/nginx/logs"
//存放切割日志目錄
targetDirPath := "/usr/local/nginx/logs/history"
//ngixn進(jìn)程ID文件
nginxPidPath := "/usr/local/nginx/logs/nginx.pid"
//檢查存放切割日志目錄是否存在,如果不存在則創(chuàng)建
finfo, errFile := os.Stat(targetDirPath)
if errFile !=nil {
errFile := os.MkdirAll(targetDirPath, 0777)
if errFile != nil {
fmt.Println("創(chuàng)建日志目錄失敗:"+errFile.Error())
return
}
} else if !finfo.IsDir() {
fmt.Println(targetDirPath+"已經(jīng)存在且不是一個(gè)目錄")
return
}
//獲取當(dāng)前日期,作為此次切割日志根目錄
t := time.Now()
nowDateTime := t.Format("2006-01-02")
logPath := targetDirPath+"/"+nowDateTime
os.MkdirAll(logPath, 0777)
//獲取nginx的進(jìn)程ID
pfile,err := os.Open(nginxPidPath)
defer pfile.Close()
if err != nil {
fmt.Println("not found nginx pid file")
return
}
pidData,_ := ioutil.ReadAll(pfile)
pid := string(pidData)
pid = strings.Replace(pid,"\n","",-1)
//遍歷日志目錄
filepath.Walk(srcDirPath,func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
} else {
//獲取切割日志路徑
targetfilePath := strings.Replace(path,srcDirPath,logPath,1)
if strings.Index(targetfilePath,"nginx.pid") != -1 {
return nil
}
//移動(dòng)文件
syscall.Rename(path,targetfilePath)
//創(chuàng)建原文件,這里不需要了,因?yàn)橹貑ginx后會(huì)自動(dòng)生成滴
// nFile,errCreate := os.Create(path)
// if errCreate != nil {
// fmt.Println("create file faild:"+errCreate.Error())
// }
// defer nFile.Close()
}
return nil
})
//平滑重啟nginx
cmd := exec.Command("kill","-USR1",pid)
_, errCmd := cmd.Output()
if errCmd != nil {
fmt.Println("重啟nginx失敗:"+errCmd.Error())
return;
}
fmt.Println("success")
新聞標(biāo)題:go語(yǔ)言如何定時(shí)執(zhí)行,怎么運(yùn)行GO語(yǔ)言的可執(zhí)行文件
網(wǎng)頁(yè)鏈接:http://chinadenli.net/article23/dsehjjs.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、手機(jī)網(wǎng)站建設(shè)、商城網(wǎng)站、定制網(wǎng)站、面包屑導(dǎo)航、關(guān)鍵詞優(yōu)化
聲明:本網(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
營(yíng)銷型網(wǎng)站建設(shè)知識(shí)