91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

解析Golang定時任務(wù)庫gron設(shè)計和原理

Linux愛好者 ? 來源:Linux愛好者 ? 作者:Linux愛好者 ? 2022-12-15 13:57 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

從 cron 說起

在 Unix-like 操作系統(tǒng)中,有一個大家都很熟悉的 cli 工具,它能夠來處理定時任務(wù),周期性任務(wù),這就是: cron。 你只需要簡單的語法控制就能實現(xiàn)任意【定時】的語義。用法上可以參考一下這個 Crontab Guru Editor[1],做的非常精巧。

cb04c2ac-7c3c-11ed-8abf-dac502259ad0.jpg

簡單說,每一個位都代表了一個時間維度,* 代表全集,所以,上面的語義是:在每天早上的4點05分觸發(fā)任務(wù)。

但 cron 畢竟只是一個操作系統(tǒng)級別的工具,如果定時任務(wù)失敗了,或者壓根沒啟動,cron 是沒法提醒開發(fā)者這一點的。并且,cron 和 正則表達式都有一種魔力,不知道大家是否感同身受,這里引用同事的一句名言:

這世界上有些語言非常相似: shell腳本, es查詢的那個dsl語言, 定時任務(wù)的crontab, 正則表達式. 他們相似就相似在每次要寫的時候基本都得重新現(xiàn)學(xué)一遍。

正巧,最近看到了 gron 這個開源項目,它是用 Golang 實現(xiàn)一個并發(fā)安全的定時任務(wù)庫。實現(xiàn)非常簡單精巧,代碼量也不多。今天我們就來一起結(jié)合源碼看一下,怎樣基于 Golang 的能力做出來一個【定時任務(wù)庫】。

gron

Gron provides a clear syntax for writing and deploying cron jobs.

gron[2] 是一個泰國小哥在 2016 年開源的作品,它的特點就在于非常簡單和清晰的語義來定義【定時任務(wù)】,你不用再去記 cron 的語法。我們來看下作為使用者怎樣上手。

首先,我們還是一個 go get 安裝依賴:

$gogetgithub.com/roylee0704/gron

假設(shè)我們期望在【時機】到了以后,要做的工作是打印一個字符串,每一個小時執(zhí)行一次,我們就可以這樣:

packagemain

import(
"fmt"
"time"
"github.com/roylee0704/gron"
)

funcmain(){
c:=gron.New()
c.AddFunc(gron.Every(1*time.Hour),func(){
fmt.Println("runseveryhour.")
})
c.Start()
}

非常簡單,而且即便是在 c.Start 之后我們依然可以添加新的定時任務(wù)進去。支持了很好的擴展性。

定時參數(shù)

注意到我們調(diào)用 gron.New().AddFunc() 時傳入了一個 gron.Every(1*time.Hour)

這里其實你可以傳入任何一個 time.Duration,從而把調(diào)度間隔從 1 小時調(diào)整到 1 分鐘甚至 1 秒。

除此之外,gron 還很貼心地封裝了一個 xtime 包用來把常見的 time.Duration 封裝起來,這里我們開箱即用。

import"github.com/roylee0704/gron/xtime"

gron.Every(1*xtime.Day)
gron.Every(1*xtime.Week)

很多時候我們不僅僅某個任務(wù)在當(dāng)天運行,還希望是我們指定的時刻,而不是依賴程序啟動時間,機械地加 24 hour。gron 對此也做了很好的支持:

gron.Every(30*xtime.Day).At("00:00")
gron.Every(1*xtime.Week).At("23:59")

我們只需指定 At("hh:mm") 就可以實現(xiàn)在指定時間執(zhí)行。

源碼解析

這一節(jié)我們來看看 gron 的實現(xiàn)原理。

所謂定時任務(wù),其實包含兩個層面:

  1. 觸發(fā)器。即我們希望這個任務(wù)在什么時間點,什么周期被觸發(fā);

  2. 任務(wù)。即我們在觸發(fā)之后,希望執(zhí)行的任務(wù),類比到我們上面示例的 fmt.Println。

對這兩個概念的封裝和擴展是一個定時任務(wù)庫必須考慮的。

而同時,我們是在 Golang 的協(xié)程上跑程序的,意味著這會是一個長期運行的協(xié)程,否則你即便指定了【一個月后干XXX】這個任務(wù),程序兩天后掛了,也就無法實現(xiàn)你的訴求了。

所以,我們還希望有一個 manager 的角色,來管理我們的一組【定時任務(wù)】,如何調(diào)度,什么時候啟動,怎么停止,啟動了以后還想加新任務(wù)是否支持。

Cron

在 gron 的體系里,Cron 對象(我們上面通過 gron.New 創(chuàng)建出來的)就是我們的 manager,而底層的一個個【定時任務(wù)】則對應(yīng)到 Cron 對象中的一個個 Entry:

//Cronprovidesaconvenientinterfaceforschedulingjobsuchastoclean-up
//databaseentryeverymonth.
//
//Cronkeepstrackofanynumberofentries,invokingtheassociatedfuncas
//specifiedbytheschedule.Itmayalsobestarted,stoppedandtheentries
//maybeinspected.
typeCronstruct{
entries[]*Entry
runningbool
addchan*Entry
stopchanstruct{}
}

//NewinstantiatesnewCroninstantc.
funcNew()*Cron{
return&Cron{
stop:make(chanstruct{}),
add:make(chan*Entry),
}
}
  • entries 就是定時任務(wù)的核心能力,它記錄了一組【定時任務(wù)】;

  • running 用來標(biāo)識這個 Cron 是否已經(jīng)啟動;

  • add 是一個channel,用來支持在 Cron 啟動后,新增的【定時任務(wù)】;

  • stop 同樣是個channel,注意到是空結(jié)構(gòu)體,用來控制 Cron 的停止。這個其實是經(jīng)典寫法了,對日常開發(fā)也有借鑒意義,我們待會兒會好好看一下。

我們觀察到,當(dāng)調(diào)用 gron.New() 方法后,得到的是一個指向 Cron 對象的指針。此時只是初始化了 stop 和 add 兩個 channel,沒有啟動調(diào)度。

Entry

重頭戲來了,Cron 里面的 []* Entry 其實就代表了一組【定時任務(wù)】,每個【定時任務(wù)】可以簡化理解為 <觸發(fā)器,任務(wù)> 組成的一個 tuple。

//Entryconsistsofascheduleandthejobtobeexecutedonthatschedule.
typeEntrystruct{
ScheduleSchedule
JobJob

//thenexttimethejobwillrun.ThisiszerotimeifCronhasnotbeen
//startedorinvalidschedule.
Nexttime.Time

//thelasttimethejobwasrun.Thisiszerotimeifthejobhasnotbeen
//run.
Prevtime.Time
}

//ScheduleistheinterfacethatwrapsthebasicNextmethod.
//
//Nextdeducesnextoccurringtimebasedontandunderlyingstates.
typeScheduleinterface{
Next(ttime.Time)time.Time
}

//JobistheinterfacethatwrapsthebasicRunmethod.
//
//Runexecutestheunderlyingfunc.
typeJobinterface{
Run()
}
  • Schedule 代表了一個【觸發(fā)器】,或者說一個定時策略。它只包含一個 Next 方法,接受一個時間點,業(yè)務(wù)要返回下一次觸發(fā)調(diào)動的時間點。

  • Job 則是對【任務(wù)】的抽象,只需要實現(xiàn)一個 Run 方法,沒有入?yún)⒊鰠ⅰ?/p>

除了這兩個核心依賴外,Entry 結(jié)構(gòu)還包含了【前一次執(zhí)行時間點】和【下一次執(zhí)行時間點】,這個目前可以忽略,只是為了輔助代碼用。

按照時間排序

//byTimeisahandywrappertochronologicallysortentries.
typebyTime[]*Entry

func(bbyTime)Len()int{returnlen(b)}
func(bbyTime)Swap(i,jint){b[i],b[j]=b[j],b[i]}

//Lessreports`earliest`timeishouldsortbeforej.
//zerotimeisnot`earliest`time.
func(bbyTime)Less(i,jint)bool{

ifb[i].Next.IsZero(){
returnfalse
}
ifb[j].Next.IsZero(){
returntrue
}

returnb[i].Next.Before(b[j].Next)
}

這里是對 Entry 列表的簡單封裝,因為我們可能同時有多個 Entry 需要調(diào)度,處理的順序很重要。這里實現(xiàn)了 sort 的接口, 有了 Len(), Swap(), Less() 我們就可以用 sort.Sort() 來排序了。

此處的排序策略是按照時間大小。

新增定時任務(wù)

我們在示例里面出現(xiàn)過調(diào)用 AddFunc() 來加入一個 gron.Every(xxx) 這樣一個【定時任務(wù)】。其實這是給用戶提供的簡單封裝。

//JobFuncisanadaptertoallowtheuseofordinaryfunctionsasgron.Job
//Iffisafunctionwiththeappropriatesignature,JobFunc(f)isahandler
//thatcallsf.
//
//todo:possiblyfuncwithparams?maybenotneeded.
typeJobFuncfunc()

//Runcallsj()
func(jJobFunc)Run(){
j()
}


//AddFuncregisterstheJobfunctionforthegivenSchedule.
func(c*Cron)AddFunc(sSchedule,jfunc()){
c.Add(s,JobFunc(j))
}

//Addappendsschedule,jobtoentries.
//
//ifcroninstantisnotrunning,addingtoentriesistrivial.
//otherwise,topreventdata-race,addsthroughchannel.
func(c*Cron)Add(sSchedule,jJob){

entry:=&Entry{
Schedule:s,
Job:j,
}

if!c.running{
c.entries=append(c.entries,entry)
return
}
c.add<-?entry
}

JobFunc 實現(xiàn)了我們上一節(jié)提到的 Job 接口,基于此,我們就可以讓用戶直接傳入一個 func() 就ok,內(nèi)部轉(zhuǎn)成 JobFunc,再利用通用的 Add 方法將其加入到 Cron 中即可。

注意,這里的 Add 方法就是新增定時任務(wù)的核心能力了,我們需要觸發(fā)器 Schedule,任務(wù) Job。并以此來構(gòu)造出一個定時任務(wù) Entry。

若 Cron 實例還沒啟動,加入到 Cron 的 entries 列表里就ok,隨后啟動的時候會處理。但如果已經(jīng)啟動了,就直接往 add 這個 channel 中塞,走額外的新增調(diào)度路徑。

啟動和停止

//Startsignalscroninstantctogetupandrunning.
func(c*Cron)Start(){
c.running=true
goc.run()
}


//Stophaltscroninstantcfromrunning.
func(c*Cron)Stop(){

if!c.running{
return
}
c.running=false
c.stop<-?struct{}{}
}

我們先 high level 地看一下一個 Cron 的啟動和停止。

  • Start 方法執(zhí)行的時候會先將 running 變量置為 true,用來標(biāo)識實例已經(jīng)啟動(啟動前后加入的定時任務(wù) Entry 處理策略是不同的,所以這里需要標(biāo)識),然后啟動一個 goroutine 來實際跑啟動的邏輯。

  • Stop 方法則會將 running 置為 false,然后直接往 stop channel 塞一個空結(jié)構(gòu)體即可。

ok,有了這個心里預(yù)期,我們來看看 c.run() 里面干了什么事:

varafter=time.After


//runthescheduler...
//
//Itneedstobeprivateasit'sresponsibleofsynchronizingacritical
//sharedstate:`running`.
func(c*Cron)run(){

vareffectivetime.Time
now:=time.Now().Local()

//tofigurenexttrigtimeforentries,referencedfromnow
for_,e:=rangec.entries{
e.Next=e.Schedule.Next(now)
}

for{
sort.Sort(byTime(c.entries))
iflen(c.entries)>0{
effective=c.entries[0].Next
}else{
effective=now.AddDate(15,0,0)//topreventphantomjobs.
}

select{
casenow=<-after(effective.Sub(now)):
???//entrieswithsametimegetsrun.
for_,entry:=rangec.entries{
ifentry.Next!=effective{
break
}
entry.Prev=now
entry.Next=entry.Schedule.Next(now)
goentry.Job.Run()
}
casee:=<-c.add:
???e.Next?=?e.Schedule.Next(time.Now())
???c.entries?=?append(c.entries,e)
case<-c.stop:
???return//terminatego-routine.
}
}
}

重點來了,看看我們是如何把上面 Cron, Entry, Schedule, Job 串起來的。

  • 首先拿到 local 的時間 now;
  • 遍歷所有 Entry,調(diào)用 Next 方法拿到各個【定時任務(wù)】下一次運行的時間點;
  • 對所有 Entry 按照時間排序(我們上面提過的 byTime);
  • 拿到第一個要到期的時間點,在 select 里面通過 time.After 來監(jiān)聽。到點了就起動新的 goroutine 跑對應(yīng) entry 里的 Job,并回到 for 循環(huán),繼續(xù)重新 sort,再走同樣的流程;
  • 若 add channel 里有新的 Entry 被加進來,就加入到 Cron 的 entries 里,觸發(fā)新的 sort;
  • 若 stop channel 收到了信號,就直接 return,結(jié)束執(zhí)行。

整體實現(xiàn)還是非常簡潔的,大家可以感受一下。

Schedule

前面其實我們暫時將觸發(fā)器的復(fù)雜性封裝在 Schedule 接口中了,但怎么樣實現(xiàn)一個 Schedule 呢?

尤其是注意,我們還支持 At 操作,也就是指定 Day,和具體的小時,分鐘。回憶一下:

gron.Every(30*xtime.Day).At("00:00")
gron.Every(1*xtime.Week).At("23:59")

這一節(jié)我們就來看看,gron.Every 干了什么事,又是如何支持 At 方法的。

//EveryreturnsaSchedulereoccurseveryperiodp,pmustbeatleast
//time.Second.
funcEvery(ptime.Duration)AtSchedule{

ifp//truncatesuptoseconds

return&periodicSchedule{
period:p,
}
}

gron 的 Every 函數(shù)接受一個 time.Duration,返回了一個 AtSchedule 接口。我待會兒會看,這里注意,Every 里面是會把【秒】級以下給截掉。

我們先來看下,最后返回的這個 periodicSchedule 是什么:

typeperiodicSchedulestruct{
periodtime.Duration
}

//Nextaddstimettounderlyingperiod,truncatesuptounitofseconds.
func(psperiodicSchedule)Next(ttime.Time)time.Time{
returnt.Truncate(time.Second).Add(ps.period)
}

//Atreturnsaschedulewhichreoccurseveryperiodp,attimet(hh:ss).
//
//Note:Atpanicswhenperiodpislessthanxtime.Day,anderrorhh:ssformat.
func(psperiodicSchedule)At(tstring)Schedule{
ifps.periodpanic("periodmustbeatleastindays")
}

//parsetnaively
h,m,err:=parse(t)

iferr!=nil{
panic(err.Error())
}

return&atSchedule{
period:ps.period,
hh:h,
mm:m,
}
}

//parsenaivelytokeniseshoursandminutes.
//
//returnserrorwheninputformatwasincorrect.
funcparse(hhmmstring)(hhint,mmint,errerror){

hh=int(hhmm[0]-'0')*10+int(hhmm[1]-'0')
mm=int(hhmm[3]-'0')*10+int(hhmm[4]-'0')

ifhh0||hh>24{
hh,mm=0,0
err=errors.New("invalidhhformat")
}
ifmm0||mm>59{
hh,mm=0,0
err=errors.New("invalidmmformat")
}

return
}

可以看到,所謂 periodicSchedule 就是一個【周期性觸發(fā)器】,只維護一個 time.Duration 作為【周期】。

periodicSchedule 實現(xiàn) Next 的方式也很簡單,把秒以下的截掉之后,直接 Add(period),把周期加到當(dāng)前的 time.Time 上,返回新的時間點。這個大家都能想到。

重點在于,對 At 能力的支持。我們來關(guān)注下 func (ps periodicSchedule) At(t string) Schedule 這個方法

  • 若周期連 1 天都不到,不支持 At 能力,因為 At 本質(zhì)是在選定的一天內(nèi),指定小時,分鐘,作為輔助。連一天都不到的周期,是要精準(zhǔn)處理的;

  • 將用戶輸入的形如 "23:59" 時間字符串解析出來【小時】和【分鐘】;

  • 構(gòu)建出一個 atSchedule 對象,包含了【周期時長】,【小時】,【分鐘】。

ok,這一步只是拿到了材料,那具體怎樣處理呢?這個還是得繼續(xù)往下走,看看 atSchedule 結(jié)構(gòu)干了什么:

typeatSchedulestruct{
periodtime.Duration
hhint
mmint
}

//resetreturnsnewDatebasedontimeinstantt,andreconfigureitshh:ss
//accordingtoatSchedule'shh:ss.
func(asatSchedule)reset(ttime.Time)time.Time{
returntime.Date(t.Year(),t.Month(),t.Day(),as.hh,as.mm,0,0,time.UTC)
}

//Nextreturns**next**time.
//iftpasseditssupposedschedule:reset(t),returnsreset(t)+period,
//elsereturnsreset(t).
func(asatSchedule)Next(ttime.Time)time.Time{
next:=as.reset(t)
ift.After(next){
returnnext.Add(as.period)
}
returnnext
}

其實只看這個 Next 的實現(xiàn)即可。我們從 periodSchedule 那里獲取了三個屬性。

在調(diào)用 Next 方法時,先做 reset,根據(jù)原有 time.Time 的年,月,日,以及用戶輸入的 At 中的小時,分鐘,來構(gòu)建出來一個 time.Time 作為新的時間點。

此后判斷是在哪個周期,如果當(dāng)前周期已經(jīng)過了,那就按照下個周期的時間點返回。

到這里,一切就都清楚了,如果我們不用 At 能力,直接 gron.Every(xxx),那么直接就會調(diào)用

t.Truncate(time.Second).Add(ps.period)

拿到一個新的時間點返回。

而如果我們要用 At 能力,指定當(dāng)天的小時,分鐘。那就會走到 periodicSchedule.At 這里,解析出【小時】和【分鐘】,最后走 Next 返回 reset 之后的時間點。

這個和 gron.Every 方法返回的 AtSchedule 接口其實是完全對應(yīng)的:

//AtScheduleextendsSchedulebyenablingperiodic-interval&time-specificsetup
typeAtScheduleinterface{
At(tstring)Schedule
Schedule
}

直接就有一個 Schedule 可以用,但如果你想針對天級以上的 duration 指定時間,也可以走 At 方法,也會返回一個 Schedule 供我們使用。

擴展性

gron 里面對于所有的依賴也都做成了【依賴接口而不是實現(xiàn)】。Cron 的 Add 函數(shù)的入?yún)⒁彩莾蓚€接口,這里可以隨意替換:func (c *Cron) Add(s Schedule, j Job)。

最核心的兩個實體依賴 Schedule, Job 都可以用你自定義的實現(xiàn)來替換掉。

如實現(xiàn)一個新的 Job:

typeReminderstruct{
Msgstring
}

func(rReminder)Run(){
fmt.Println(r.Msg)
}

事實上,我們上面提到的 periodicSchedule 以及 atSchedule 就是 Schedule 接口的具體實現(xiàn)。我們也完全可以不用 gron.Every,而是自己寫一套新的 Schedule 實現(xiàn)。只要實現(xiàn) Next(p time.Duration) time.Time 即可。

我們來看一個完整用法案例:

packagemain

import(
"fmt"
"github.com/roylee0704/gron"
"github.com/roylee0704/gron/xtime"
)

typePrintJobstruct{Msgstring}

func(pPrintJob)Run(){
fmt.Println(p.Msg)
}

funcmain(){

var(
//schedules
daily=gron.Every(1*xtime.Day)
weekly=gron.Every(1*xtime.Week)
monthly=gron.Every(30*xtime.Day)
yearly=gron.Every(365*xtime.Day)

//contrivedjobs
purgeTask=func(){fmt.Println("purgeagedrecords")}
printFoo=printJob{"Foo"}
printBar=printJob{"Bar"}
)

c:=gron.New()

c.Add(daily.At("12:30"),printFoo)
c.AddFunc(weekly,func(){fmt.Println("Everyweek")})
c.Start()

//JobsmayalsobeaddedtoarunningGron
c.Add(monthly,printBar)
c.AddFunc(yearly,purgeTask)

//StopGron(runningjobsarenothalted).
c.Stop()
}

經(jīng)典寫法-控制退出

這里我們還是要聊一下 Cron 里控制退出的經(jīng)典寫法。我們把其他不相關(guān)的部分清理掉,只留下核心代碼:

typeCronstruct{
stopchanstruct{}
}

func(c*Cron)Stop(){
c.stop<-?struct{}{}
}

func(c*Cron)run(){

for{
select{
case<-c.stop:
???return//terminatego-routine.
}
}
}

空結(jié)構(gòu)體能夠最大限度節(jié)省內(nèi)存,畢竟我們只是需要一個信號。核心邏輯用 for + select 的配合,這樣當(dāng)我們需要結(jié)束時可以立刻響應(yīng)。非常經(jīng)典,建議大家日常有需要的時候采用。

結(jié)語

gron 整體代碼其實只在 cron.go 和 schedule.go 兩個文件,合起來代碼不過 300 行,非常精巧,基本沒有冗余,擴展性很好,是非常好的入門材料。

不過,作為一個 cron 的替代品,其實 gron 還是有自己的問題的。簡單講就是,如果我重啟了一個EC2實例,那么我的 cron job 其實也還會繼續(xù)執(zhí)行,這是落盤的,操作系統(tǒng)級別的支持。

但如果我執(zhí)行 gron 的進程掛掉了,不好意思,那就完全涼了。你只有重啟,然后再把所有任務(wù)加回來才行。而我們既然要用 gron,是很有可能定一個幾天后,幾個星期后,幾個月后這樣的觸發(fā)器的。誰能保證進程一直活著呢?連機子本身都可能重啟。

所以,我們需要一定的機制來保證 gron 任務(wù)的可恢復(fù)性,將任務(wù)落盤,持久化狀態(tài)信息,算是個思考題,這里大家可以考慮一下怎么做。

審核編輯 :李倩



聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    7402

    瀏覽量

    129348
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4968

    瀏覽量

    74009

原文標(biāo)題:解析 Golang 定時任務(wù)庫 gron 設(shè)計和原理

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    深入解析xx555系列精密定時器:功能、應(yīng)用與設(shè)計要點

    深入解析xx555系列精密定時器:功能、應(yīng)用與設(shè)計要點 在電子工程師的工具箱中,定時器是一種至關(guān)重要的組件,它廣泛應(yīng)用于各種電子設(shè)備中,用于實現(xiàn)精確的時間控制。今天,我們將深入探討xx555系列精密
    的頭像 發(fā)表于 02-10 15:40 ?304次閱讀

    深入解析 LM555 定時器:特性、應(yīng)用與設(shè)計要點

    深入解析 LM555 定時器:特性、應(yīng)用與設(shè)計要點 一、引言 在電子工程師的工具箱中,定時器芯片是常用的基礎(chǔ)元件之一。而 TI 公司的 LM555 定時器,以其高穩(wěn)定性、多種工作模式和
    的頭像 發(fā)表于 02-10 15:35 ?252次閱讀

    大模型ai驅(qū)動的發(fā)射任務(wù)智能調(diào)度分系統(tǒng):功能特點與平臺架構(gòu)解析

    ? ? 大模型AI驅(qū)動的發(fā)射任務(wù)智能調(diào)度分系統(tǒng):航天智能化核心技術(shù)解析 ? ?北京華盛恒輝大模型AI驅(qū)動的發(fā)射任務(wù)智能調(diào)度分系統(tǒng)作為航天領(lǐng)域智能化升級的關(guān)鍵支撐,通過多源數(shù)據(jù)整合、動態(tài)資源調(diào)配與智能
    的頭像 發(fā)表于 12-19 14:10 ?440次閱讀

    Linux-RT特點及簡單應(yīng)用

    :Linux-RT支持優(yōu)先級繼承(Priority Inheritance),避免了優(yōu)先級反轉(zhuǎn)問題,提高了實時任務(wù)的響應(yīng)性能。 標(biāo)準(zhǔn)Linux內(nèi)核的調(diào)度器(也稱為CFS調(diào)度器)和實時內(nèi)核調(diào)度器 標(biāo)準(zhǔn)Linux
    發(fā)表于 12-05 07:37

    HTTP開發(fā)必備:核心與httpplus擴展應(yīng)用示例全攻略

    HTTP開發(fā)的必備參考!本文匯總核心基礎(chǔ)操作與httpplus擴展高級特性,通過示例解析,讓你快速上手各類HTTP開發(fā)需求。
    的頭像 發(fā)表于 09-20 15:19 ?3207次閱讀
    HTTP開發(fā)必備:核心<b class='flag-5'>庫</b>與httpplus擴展<b class='flag-5'>庫</b>應(yīng)用示例全攻略

    電磁環(huán)境數(shù)據(jù)管理系統(tǒng)平臺軟件解析

    電磁環(huán)境數(shù)據(jù)管理平臺軟件解析(精簡版)
    的頭像 發(fā)表于 09-15 21:00 ?353次閱讀
    電磁環(huán)境數(shù)據(jù)<b class='flag-5'>庫</b>管理系統(tǒng)平臺軟件<b class='flag-5'>解析</b>

    Crontab定時任務(wù)完全指南

    在凌晨3點,當(dāng)大多數(shù)人還在熟睡時,一位運維工程師的手機突然響起——線上數(shù)據(jù)備份失敗了。他匆忙起床,打開電腦,手動執(zhí)行備份腳本,整個過程耗時2小時。這樣的場景,在我剛?cè)胄袝r經(jīng)常遇到。直到我真正掌握了crontab定時任務(wù),才徹底擺脫了"人肉運維"的窘境。
    的頭像 發(fā)表于 09-05 10:03 ?867次閱讀

    Task任務(wù):LuatOS實現(xiàn)“任務(wù)級并發(fā)”的核心引擎

    LuatOS應(yīng)用程序運行的核心大腦——所有LuatOS應(yīng)用項目都會使用到sys核心。 ? ?sys核心提供了四大類功能: Task任務(wù) Message消息 Timer定時器 Run
    的頭像 發(fā)表于 08-28 13:49 ?526次閱讀
    Task<b class='flag-5'>任務(wù)</b>:LuatOS實現(xiàn)“<b class='flag-5'>任務(wù)</b>級并發(fā)”的核心引擎

    揭秘LuatOS Task:多任務(wù)管理的“智能中樞”

    ,也是LuatOS應(yīng)用程序運行的核心大腦——所有LuatOS應(yīng)用項目都會使用到sys核心。 ? ?sys核心提供了四大類功能: Task任務(wù) Message消息 Timer定時
    的頭像 發(fā)表于 08-28 13:48 ?661次閱讀
    揭秘LuatOS Task:多<b class='flag-5'>任務(wù)</b>管理的“智能中樞”

    【HZ-T536開發(fā)板免費體驗】5、安裝sqlite3和使用golang讀寫數(shù)據(jù)

    如果想在嵌入式設(shè)備上實現(xiàn)簡單的設(shè)備管理功能,需要數(shù)據(jù)和服務(wù)后端程序。服務(wù)端程序,我更傾向使用golang來實現(xiàn)。 安裝sqlite3,使用ubuntu環(huán)境,可以直接用apt install安裝程序
    發(fā)表于 08-26 00:04

    使用C#實現(xiàn)西門子PLC數(shù)據(jù)定時讀取保存

    在平時開發(fā)中,我們時常會遇到需要后臺靜默運行的應(yīng)用場景,這些程序不需要用戶的直接操作或界面展示,而是專注于定時任務(wù)的執(zhí)行。比如說,我們需要定期從西門子PLC(可編程邏輯控制器)中讀取數(shù)據(jù)并進行保存,以便后續(xù)分析使用。
    的頭像 發(fā)表于 08-07 16:17 ?2474次閱讀
    使用C#實現(xiàn)西門子PLC數(shù)據(jù)<b class='flag-5'>定時</b>讀取保存

    睿擎多核 SMP 開發(fā):極簡開發(fā),超強性能——睿擎派開發(fā)板0元試用

    在工業(yè)控制、邊緣計算等場景中,MPU多核架構(gòu)的性能潛力常因開發(fā)復(fù)雜度難以釋放。實時任務(wù)(如運動控制、高速采集)與計算密集型任務(wù)(如UI交互、網(wǎng)絡(luò)通信、協(xié)議解析)混合運行,導(dǎo)致以下問題:實時性劣化
    的頭像 發(fā)表于 05-29 17:04 ?1467次閱讀
    睿擎多核 SMP 開發(fā):極簡開發(fā),超強性能——睿擎派開發(fā)板0元試用

    快速入門——LuatOS:sys任務(wù)管理實戰(zhàn)攻略!

    的開發(fā)者,這里將用最簡明的步驟,助你輕松實現(xiàn)多任務(wù)應(yīng)用開發(fā)! sys是LuatOS的核心系統(tǒng)調(diào)度,它基于Lua協(xié)程機制實現(xiàn)了實時多任務(wù)調(diào)度、定時
    的頭像 發(fā)表于 05-29 14:36 ?865次閱讀
    快速入門——LuatOS:sys<b class='flag-5'>庫</b>多<b class='flag-5'>任務(wù)</b>管理實戰(zhàn)攻略!

    linux服務(wù)器挖礦病毒處理方案

    情況說明:挖礦進程被隱藏(CPU占用50%,htop/top卻看不到異常進程),結(jié)束挖礦進程后馬上又會運行起來(crontab -l查看發(fā)現(xiàn)沒有定時任務(wù))。
    的頭像 發(fā)表于 04-09 10:33 ?1250次閱讀
    linux服務(wù)器挖礦病毒處理方案

    【第四章 定時任務(wù)】手把手教你玩轉(zhuǎn)新版正點原子云

    【第四章 定時任務(wù)】手把手教你玩轉(zhuǎn)新版正點原子云 承接上篇,除了報警聯(lián)動這個功能,原子云還有一個特色功能也是各開發(fā)者喜歡用的,定時任務(wù)功能。 【正點原子】云平臺:原子云(點擊登錄原子云) 前言
    發(fā)表于 03-13 10:19