在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

Go預(yù)言實(shí)現(xiàn)的后段狀態(tài)推送設(shè)計(jì)與實(shí)踐

Linux愛好者 ? 來(lái)源:segmentfault ? 作者:hammermax ? 2021-05-10 17:46 ? 次閱讀

【導(dǎo)讀】本文是一篇Go預(yù)言實(shí)現(xiàn)的后段狀態(tài)推送設(shè)計(jì)與實(shí)踐,寫的非常詳細(xì),一起來(lái)學(xué)習(xí)吧!

狀態(tài)推送

前言:掃碼登錄功能自微信提出后,越來(lái)越多的被應(yīng)用于各個(gè)web與app。這兩天公司要做一個(gè)掃碼登錄功能,在leader的技術(shù)支持幫助下(基本都靠leader排坑),終于將服務(wù)搭建起來(lái),并且支持上萬(wàn)并發(fā)。

長(zhǎng)連接選擇

決定做掃碼登錄功能之后,在網(wǎng)上查看了很多的相關(guān)資料。對(duì)于掃碼登錄的實(shí)現(xiàn)方式有很多,淘寶用的是輪詢,微信用長(zhǎng)連接,QQ用輪詢……。方式雖多,但目前看來(lái)大體分為兩種,1:輪詢,2:長(zhǎng)連接。(兩種方式各有利弊吧,我研究不深,優(yōu)缺點(diǎn)就不贅述了)

在和leader討論之后選擇了用長(zhǎng)連接的方式。所以對(duì)長(zhǎng)連接的實(shí)現(xiàn)方式調(diào)研了很多:

1.微信長(zhǎng)連接:通過(guò)動(dòng)態(tài)加載script的方式實(shí)現(xiàn)。

這種方式好在沒有跨域問題。

2.websocket長(zhǎng)連接:在PC端與服務(wù)端搭起一條長(zhǎng)連接后,服務(wù)端主動(dòng)不斷地向PC端推送狀態(tài)。這應(yīng)該是最完美的做法了。

3.我使用的長(zhǎng)連接:PC端向服務(wù)端發(fā)送請(qǐng)求,服務(wù)端并不立即響應(yīng),而是hold住,等到用戶掃碼之后再響應(yīng)這個(gè)請(qǐng)求,響應(yīng)后連接斷開。

為什么不采用websocket呢?因?yàn)楫?dāng)時(shí)比較急、而對(duì)于websocket的使用比較陌生,所以沒有使用。不過(guò)我現(xiàn)在這種做法在資源使用上比websocket低很多。

接口設(shè)計(jì)

(本來(lái)想把leader畫的一副架構(gòu)圖放上來(lái),但涉及到公司,不敢)

自己畫的一副流程圖

96217642-b0bf-11eb-bf61-12bb97331649.png

稍微解釋一下:

第一條連接:打開PC界面的時(shí)候向服務(wù)端發(fā)送請(qǐng)求并建立長(zhǎng)連接(1)。當(dāng)APP成功掃碼后(2),響應(yīng)這次請(qǐng)求(3)。

第二條連接類似。

分析得出我們的服務(wù)只需要兩個(gè)接口即可

1.與PC建立長(zhǎng)連接的接口

2.接收APP端數(shù)據(jù)并將數(shù)據(jù)發(fā)送給前端的接口

再細(xì)想可將這兩個(gè)接口抽象為:

1.PC獲取狀態(tài)接口:get

2.APP設(shè)置狀態(tài)接口:set

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

用GO寫的(不多嗶嗶)

長(zhǎng)連接的根本原理:連接請(qǐng)求后,服務(wù)端利用channel阻塞住。等到channel中有value后,將value響應(yīng)

Router

func Router(){

http.HandleFunc(“/status/get”, Get)

http.HandleFunc(“/status/set”, Set)

}

GET

每一條連接需要有一個(gè)KEY作標(biāo)識(shí),不然APP設(shè)置的狀態(tài)不知道該發(fā)給那臺(tái)PC。每一條連接即一個(gè)channel

var Status map[string](chan string) = make(map[string](chan string))

func Get(w http.ResponseWriter, r *http.Request){

//接收key的操作

key = //PC在請(qǐng)求接口時(shí)帶著的key

Status[key] = make(chan string) //不需要緩沖區(qū)

value := 《-Status[key]

ResponseJson(w, 0, “success”, value) //自己封的響應(yīng)JSON方法

}

SET

APP掃碼后可以得到二維碼中的KEY,同時(shí)將想給PC發(fā)送的VALUE一起發(fā)送給服務(wù)端

func Set(w http.ResponseWriter, r *http.Request){

key =

value = //向PC傳遞的值

Status[key] 《- value

}

這就是實(shí)現(xiàn)的最基本原理。

接下來(lái)我們一點(diǎn)點(diǎn)實(shí)現(xiàn)其他的功能。

1.超時(shí)

從網(wǎng)上找了很多資料,大部分都說(shuō)這種方式

srv := &http.Server{

ReadTimeout: 5 * time.Second,

WriteTimeout: 10 * time.Second,

}

log.Println(srv.ListenAndServe())

這種方式確實(shí)是設(shè)置讀超時(shí)與寫超時(shí)。但(親測(cè))這種超時(shí)方式并不友善,假如現(xiàn)在WriteTimeout是10s,PC端請(qǐng)求過(guò)來(lái)之后,長(zhǎng)連接建立。PC處于pending狀態(tài),并且服務(wù)端被channel阻塞住。10s之后,由于超時(shí)連接失效(并沒有斷,我也不了解其中原理)。PC并不知道連接斷了,依然處于pending狀態(tài),服務(wù)端的這個(gè)goroutine依然被阻塞在這里。這個(gè)時(shí)候我調(diào)用set接口,第一次調(diào)用沒用反應(yīng),但第二次調(diào)用PC端就能成功接收value。

99289618-b0bf-11eb-bf61-12bb97331649.png

從圖可以看出,我設(shè)置的WriteTimeout為10s,但這條長(zhǎng)連接即使15s依然能收到成功響應(yīng)。(ps:我調(diào)用了兩次set接口,第一次沒有反應(yīng))

研究后決定不使用這種方式設(shè)置超時(shí),采用接口內(nèi)部定時(shí)的方式實(shí)現(xiàn)超時(shí)返回

select {

case 《-`Timer`:

utils.ResponseJson(w, -1, “timeout”, nil)

case value := 《-statusChan:

utils.ResponseJson(w, 0, “success”, value)

}

Timer即為定時(shí)器。剛開始Timer是這樣定義的

Timer := time.After(60 * time.Second)

60s后Timer會(huì)自動(dòng)返回一個(gè)值,這時(shí)上面的通道就開了,響應(yīng)timeout

但這樣做有一個(gè)弊端,這個(gè)定時(shí)器一旦創(chuàng)建就必須等待60s,并且我沒想到辦法提前將定時(shí)器關(guān)了。如果這個(gè)長(zhǎng)連接剛建立后5s就被響應(yīng),那么這個(gè)定時(shí)器就要多存在55s。這樣對(duì)資源是一種浪費(fèi),并不合理。

這里選用了context作為定時(shí)器

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(Timeout)*time.Second)

defer cancel()

select {

case 《-ctx.Done():

utils.ResponseJson(w, -1, “timeout”, nil)

case result := 《-Status[key]:

utils.ResponseJson(w, 0, “success”, result)

}

ctx在初始化的時(shí)候就設(shè)置了超時(shí)時(shí)間time.Duration(Timeout)*time.Second

超時(shí)之后ctx.Done()返回完成,起到定時(shí)作用。如果沒有cancel()則會(huì)有一樣的問題。原因如下

993413e4-b0bf-11eb-bf61-12bb97331649.png

context對(duì)比time包。提供了手動(dòng)關(guān)閉定時(shí)器的方法cancel()

只要get請(qǐng)求結(jié)束,都會(huì)去關(guān)閉定時(shí)器,這樣可以避免資源浪費(fèi)(一定程度避免內(nèi)存泄漏)。

注即使golang官方文檔中,也推薦defer cancel()這樣寫

993ef908-b0bf-11eb-bf61-12bb97331649.jpg

官方文檔也寫到:即使ctx會(huì)在到期時(shí)關(guān)閉,但在任何場(chǎng)景手動(dòng)調(diào)用cancel都是很好的做法。

2.多機(jī)支持

服務(wù)如果只部署在一臺(tái)機(jī)器上,萬(wàn)一機(jī)器跪了,那就全跪了。

所以我們的服務(wù)必須同時(shí)部署在多個(gè)機(jī)器上工作。即使其中一臺(tái)掛了,也不影響服務(wù)使用。

這個(gè)圖不會(huì)畫,只能用leader的圖了

99ae677a-b0bf-11eb-bf61-12bb97331649.jpg

在項(xiàng)目初期討論的時(shí)候leader給出了兩種方案。1.如圖使用redis做多機(jī)調(diào)度。2.使用zookeeper將消息發(fā)送給多機(jī)

因?yàn)楝F(xiàn)在是用redis做的,只講述下redis的實(shí)現(xiàn)。(但依賴redis并不是很好,多機(jī)的負(fù)載均衡還要依賴其他工具。zookeeper能夠解決這個(gè)問題,之后會(huì)將redis換成zookeeper)

首先我們要明確多機(jī)的難點(diǎn)在哪?

我們有兩個(gè)接口,get、set。get是給前端建立長(zhǎng)連接用的。set是后端設(shè)置狀態(tài)用的。

假設(shè)有兩臺(tái)機(jī)器A、B。若前端的請(qǐng)求發(fā)送到A機(jī)器上,即A機(jī)器與前端連接,此時(shí)后端調(diào)用set接口,如果調(diào)用的是A機(jī)器的set接口,那是最好,長(zhǎng)連接就能成功響應(yīng)。但如果調(diào)用了B機(jī)器的set接口,B機(jī)器上又沒有這條連接,那么這條連接就無(wú)法響應(yīng)。

所以難點(diǎn)在于如何將同一個(gè)key的get、set分配到一臺(tái)機(jī)器。

有人給我提過(guò)一個(gè)意見:在做負(fù)載均衡的時(shí)候,就將連接分配到指定機(jī)器。剛開始我覺的很有道理,但細(xì)細(xì)想,如果這樣做,在以后如果要加機(jī)器或減機(jī)器的時(shí)候會(huì)很麻煩。對(duì)橫向的增減機(jī)器不友善。

最后我還是采用了leader給出的方案:用redis綁定key與機(jī)器的關(guān)系

即前端請(qǐng)求到一臺(tái)機(jī)器上,以key做鍵,以機(jī)器IP做值放在redis里面。后端請(qǐng)求set接口時(shí)先用key去redis里面拿到機(jī)器IP,再將value發(fā)送到這臺(tái)機(jī)器上。

此時(shí)就多了一個(gè)接口,用于機(jī)器內(nèi)部相互調(diào)用

ChanSet

func Router(){

http.HandleFunc(“/status/get”, Get)

http.HandleFunc(“/status/set”, Set)

http.HandleFunc(“/channel/set”, ChanSet)

}

func ChanSet(w http.ResponseWriter, r *http.Request){

key =

value =

Status[key] 《- value

}

GET

func Get(w http.ResponseWriter, r *http.Request){

IP = getLocalIp() //得到本機(jī)IP

RedisSet(key, IP) //以key做鍵,IP做值放入redis

Status[key] 《- value

}

SET

func Set(w http.ResponseWriter, r *http.Request){

IP = RedisGet(key) //用key去取對(duì)應(yīng)機(jī)器的IP

Post(IP, key, value) //將key與value都發(fā)送給這臺(tái)機(jī)器

}

注這里相當(dāng)于用redis sentinel做多臺(tái)機(jī)器的通信。哨兵會(huì)幫我們將數(shù)據(jù)同步到所有機(jī)器上

這樣即可實(shí)現(xiàn)多機(jī)支持

3.跨域

剛部署到線上的時(shí)候,第一次嘗試就跪了。查看錯(cuò)誤(Access-Control-Allow-Origin)

因?yàn)榍岸耸峭ㄟ^(guò)AJAX請(qǐng)求的長(zhǎng)連接服務(wù),所以存在跨域問題。

在服務(wù)端設(shè)置允許跨域

func Get(w http.ResponseWriter, r *http.Request){

w.Header().Set(“Access-Control-Allow-Origin”, “*”)

w.Header().Add(“Access-Control-Allow-Headers”, “Content-Type”)

}

若是像微信的做法,動(dòng)態(tài)的加載script方式,則沒有跨域問題。

服務(wù)端直接允許跨域,可能會(huì)有安全問題,但我不是很了解,這里為了使用,就允許跨域了。

4.Map并發(fā)讀寫問題

跨域問題解決之后,線上可以正常使用了。緊接著請(qǐng)測(cè)試同學(xué)壓測(cè)了一下。

預(yù)期單機(jī)并發(fā)10000以上,測(cè)試同學(xué)直接壓了10000,服務(wù)掛了。

可能預(yù)期有點(diǎn)高,5000吧,于是壓了5000,服務(wù)掛了。

1000呢,服務(wù)掛了。

100,服務(wù)掛了。

……

這下豁然開朗,不可能是機(jī)器問題,絕對(duì)是有BUG

看了下報(bào)錯(cuò)

9a396aaa-b0bf-11eb-bf61-12bb97331649.jpg

去看了下官方文檔

9a43e4da-b0bf-11eb-bf61-12bb97331649.png

Map是不能并發(fā)的寫操作,但可以并發(fā)的讀。

原來(lái)對(duì)Map操作是這樣寫的

func Get(w http.ResponseWriter, r *http.Request){

`Status[key] = make(chan string)`

`defer close(Status[key])`

select {

case 《-ctx.Done():

utils.ResponseJson(w, -1, “timeout”, nil)

case `result := 《-Status[key]`:

utils.ResponseJson(w, 0, “success”, result)

}

}

func ChanSet(w http.ResponseWriter, r *http.Request){

`Status[key] 《- value`

}

Status[key] = make(chan string)在Status(map)里面初始化一個(gè)通道,是map的寫操作

result := 《-Status[key]從Status[key]通道中讀取一個(gè)值,由于是通道,這個(gè)值取出來(lái)后,通道內(nèi)就沒有了,所以這一步也是對(duì)map的寫操作

Status[key] 《- value向Status[key]內(nèi)放入一個(gè)值,map的寫操作

由于這三處操作的是一個(gè)map,所以要加同一把鎖

var Mutex sync.Mutex

func Get(w http.ResponseWriter, r *http.Request){

//這里是同組大佬教我的寫法,通道之間的拷貝傳遞的是指針,即statusChan與Status[key]指向的是同一個(gè)通道

statusChan := make(chan string)

Mutex.Lock()

Status[key] = statusChan

Mutex.Unlock()

//在連接結(jié)束后將這些資源都釋放

defer func(){

Mutex.Lock()

delete(Status, key)

Mutex.Unlock()

close(statusChan)

RedisDel(key)

}()

select {

case 《-ctx.Done():

utils.ResponseJson(w, -1, “timeout”, nil)

case result := 《-statusChan:

utils.ResponseJson(w, 0, “success”, result)

}

}

func ChanSet(w http.ResponseWriter, r *http.Request){

Mutex.Lock()

Status[key] 《- value

Mutex.Unlock()

}

到現(xiàn)在,服務(wù)就可以正常使用了,并且支持上萬(wàn)并發(fā)。

5.Redis過(guò)期時(shí)間

服務(wù)正常使用之后,leader review代碼,提出redis的數(shù)據(jù)為什么不設(shè)置過(guò)期時(shí)間,反而要自己手動(dòng)刪除。我一想,對(duì)啊。

于是設(shè)置了過(guò)期時(shí)間并且將RedisDel(key)刪了。

設(shè)置完之后不出意外的服務(wù)跪了。

究其原因

我用一個(gè)key=1請(qǐng)求get,會(huì)在redis內(nèi)存儲(chǔ)一條數(shù)據(jù)記錄(1 =》 Ip)。如果我set了這條連接,按之前的邏輯會(huì)將redis里的這條數(shù)據(jù)刪掉,而現(xiàn)在是等待它過(guò)期。若是在過(guò)期時(shí)間內(nèi),再次以這個(gè)key=1,調(diào)用set接口。set接口依然會(huì)從redis中拿到IP,Post數(shù)據(jù)到ChanSet接口。而ChanSet中Status[key] 《- value由于Status[key]是關(guān)閉的,會(huì)阻塞在這里,阻塞不要緊,但之前這里加了鎖,導(dǎo)致整個(gè)程序都阻塞在這里。

這里和leader討論過(guò),仍使用redis過(guò)期時(shí)間但需要修復(fù)這個(gè)Bug

func ChanSet(w http.ResponseWriter, r *http.Request){

Mutex.Lock()

ch := Status[key]

Mutex.Unlock()

if ch != nil {

ch 《- value

}

}

不過(guò)這樣有一個(gè)問題,就是同一個(gè)key,在過(guò)期時(shí)間內(nèi)是無(wú)法多次使用的。不過(guò)這與業(yè)務(wù)要求并不沖突。

6.Linux文件最大句柄數(shù)

在給測(cè)試同學(xué)測(cè)試之前,自己也壓測(cè)了一下。不過(guò)剛上來(lái)就瘋狂報(bào)錯(cuò),“%¥#@¥……%……%%..too many fail open.。.”

搜索結(jié)果是linux默認(rèn)最大句柄數(shù)1024.

開了下自己的機(jī)器 ulimit -a 果然1024。修改(修改方法不多BB)

7.同時(shí)監(jiān)聽兩個(gè)端口

服務(wù)有兩個(gè)API,get是給前端使用的,對(duì)外開放。set是給后端使用的,內(nèi)部接口。所以這兩個(gè)接口需要放在兩個(gè)端口上。

由于http.ListenAndServe()本身有阻塞,故第一個(gè)監(jiān)聽需要一個(gè)goroutine

go http.ListenAndServe(“:11000”, FrontendMux) //對(duì)外開放的端口

http.ListenAndServe(“:11001”, BackendMux) //內(nèi)部使用的端口

原文標(biāo)題:Golang-長(zhǎng)連接-狀態(tài)推送

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

責(zé)任編輯:haq

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

    關(guān)注

    9

    文章

    2096

    瀏覽量

    154404
  • 連接
    +關(guān)注

    關(guān)注

    2

    文章

    96

    瀏覽量

    20994

原文標(biāo)題:Golang-長(zhǎng)連接-狀態(tài)推送

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    后段刻蝕工藝(BEOL ETCH)詳解

    后段刻蝕工藝(Back-End of Line ETCH,簡(jiǎn)稱BEOL ETCH)作為集成電路制造的重要環(huán)節(jié),其復(fù)雜性與重要性毋庸置疑。 ? ? 什么是BEOL ETCH BEOL是指從金屬互連開始
    的頭像 發(fā)表于 12-31 09:44 ?230次閱讀

    在學(xué)習(xí)go語(yǔ)言的過(guò)程踩過(guò)的坑

    作為一個(gè)5年的phper,這兩年公司和個(gè)人都在順應(yīng)技術(shù)趨勢(shì),新項(xiàng)目慢慢從php轉(zhuǎn)向了go語(yǔ)言,從2021年到現(xiàn)在,筆者手上也先后開發(fā)了兩個(gè)go項(xiàng)目。在學(xué)習(xí)go語(yǔ)言的過(guò)程中也學(xué)習(xí)并總結(jié)了一些相關(guān)的東西,這篇文章就分享下自己踩過(guò)的一
    的頭像 發(fā)表于 11-11 09:22 ?183次閱讀

    go語(yǔ)言如何解決并發(fā)問題

    作為一個(gè)后端開發(fā),日常工作中接觸最多的兩門語(yǔ)言就是PHP和GO了。無(wú)可否認(rèn),PHP確實(shí)是最好的語(yǔ)言(手動(dòng)狗頭哈哈),寫起來(lái)真的很舒爽,沒有任何心智負(fù)擔(dān),字符串和整型壓根就不用區(qū)分,開發(fā)速度真的是比
    的頭像 發(fā)表于 10-23 13:38 ?153次閱讀
    <b class='flag-5'>go</b>語(yǔ)言如何解決并發(fā)問題

    谷歌開始推送Android 15穩(wěn)定版

    近日,谷歌正式向Pixel系列設(shè)備推送了Android 15穩(wěn)定版操作系統(tǒng)。目前,已有部分Pixel設(shè)備率先完成了系統(tǒng)升級(jí),預(yù)計(jì)本周晚些時(shí)候,更大規(guī)模的更新推送將全面展開。
    的頭像 發(fā)表于 10-17 16:12 ?1639次閱讀

    三十分鐘入門基礎(chǔ)Go Java小子版

    前言 Go語(yǔ)言定義 Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開發(fā)的一種靜態(tài)、強(qiáng)類型、編譯型語(yǔ)言。Go 語(yǔ)言
    的頭像 發(fā)表于 08-12 14:32 ?759次閱讀
    三十分鐘入門基礎(chǔ)<b class='flag-5'>Go</b> Java小子版

    如何在FPGA中實(shí)現(xiàn)狀態(tài)機(jī)

    在FPGA(現(xiàn)場(chǎng)可編程門陣列)中實(shí)現(xiàn)狀態(tài)機(jī)是一種常見的做法,用于控制復(fù)雜的數(shù)字系統(tǒng)行為。狀態(tài)機(jī)能夠根據(jù)當(dāng)前的輸入和系統(tǒng)狀態(tài),決定下一步的動(dòng)作和新的狀態(tài)。這里,我們將詳細(xì)探討如何在FPG
    的頭像 發(fā)表于 07-18 15:57 ?665次閱讀

    如何用C語(yǔ)言實(shí)現(xiàn)高效查找(二分法)

    今天給分享一下使用C語(yǔ)言實(shí)現(xiàn)二分算法,主要包含以下幾部分內(nèi)容:二分查找算法介紹二分查找算法使用場(chǎng)景二分查找算法代碼實(shí)現(xiàn)二分查找算法實(shí)現(xiàn)過(guò)程用C語(yǔ)言實(shí)現(xiàn)二分法查找二分查找也稱折半查找
    的頭像 發(fā)表于 06-04 08:04 ?1209次閱讀
    如何用C語(yǔ)<b class='flag-5'>言實(shí)現(xiàn)</b>高效查找(二分法)

    AD7616的16路采樣通道,如何實(shí)現(xiàn)對(duì)通道狀態(tài)的實(shí)時(shí)自檢,監(jiān)測(cè)通道狀態(tài)是否正常?

    AD7616的16路采樣通道,如何實(shí)現(xiàn)對(duì)通道狀態(tài)的實(shí)時(shí)自檢,監(jiān)測(cè)通道狀態(tài)是否正常? 1)手冊(cè)中通信自測(cè)功能是不是實(shí)現(xiàn)這個(gè)功能的?如果是,這個(gè)只是實(shí)現(xiàn)
    發(fā)表于 05-27 08:07

    使用C語(yǔ)言實(shí)現(xiàn)的CRC計(jì)算單元的例子

    使用C語(yǔ)言實(shí)現(xiàn)的CRC計(jì)算單元的例子
    的頭像 發(fā)表于 05-16 16:16 ?1036次閱讀

    請(qǐng)問STVP+COSMIC環(huán)境下的go to definition怎么用?

    STVP+COSMIC環(huán)境下的go to definition怎么用? 我現(xiàn)在go to definition在一個(gè)宏定義的時(shí)候有效果,但是函數(shù)什么的沒用,是怎么回事呢,是不是工程里面沒有設(shè)置好,求大家?guī)蛶兔Γ?/div>
    發(fā)表于 05-11 06:11

    C語(yǔ)言實(shí)現(xiàn)狀態(tài)機(jī)設(shè)計(jì)的技巧與策略

    在嵌入式環(huán)境中,由于存儲(chǔ)空間比較小,因此把它們?nèi)慷x成宏。此外,為了降低執(zhí)行時(shí)間的不確定性,我們使用O(1)的跳轉(zhuǎn)表來(lái)模擬狀態(tài)的跳轉(zhuǎn)。
    發(fā)表于 04-23 16:32 ?2697次閱讀
    C語(yǔ)<b class='flag-5'>言實(shí)現(xiàn)狀態(tài)</b>機(jī)設(shè)計(jì)的技巧與策略

    嵌入式編程,如何用 C 語(yǔ)言實(shí)現(xiàn)狀態(tài)機(jī)設(shè)計(jì)?

    狀態(tài)機(jī)模式是一種行為模式,通過(guò)多態(tài)實(shí)現(xiàn)不同狀態(tài)的調(diào)轉(zhuǎn)行為的確是一種很好的方法,只可惜在嵌入式環(huán)境下,有時(shí)只能寫純C代碼,并且還需要考慮代碼的重入和多任務(wù)請(qǐng)求跳轉(zhuǎn)等情形,因此實(shí)現(xiàn)起來(lái)著實(shí)
    發(fā)表于 04-23 11:00

    C語(yǔ)言實(shí)現(xiàn)Web參數(shù)傳遞

    電子發(fā)燒友網(wǎng)站提供《C語(yǔ)言實(shí)現(xiàn)Web參數(shù)傳遞.docx》資料免費(fèi)下載
    發(fā)表于 03-24 09:14 ?2次下載

    日月光擬收購(gòu)英飛凌兩座后段封測(cè)廠

    近日,半導(dǎo)體封測(cè)領(lǐng)域的領(lǐng)軍企業(yè)日月光投控與知名芯片制造商英飛凌共同宣布,雙方已正式簽署收購(gòu)協(xié)議。根據(jù)該協(xié)議,日月光投控將以6258.9萬(wàn)歐元的價(jià)格,收購(gòu)英飛凌位于菲律賓甲美地市及韓國(guó)天安市的兩座后段封測(cè)廠。
    的頭像 發(fā)表于 02-25 11:11 ?777次閱讀

    卡爾曼濾波算法c語(yǔ)言實(shí)現(xiàn)方法

    卡爾曼濾波(Kalman Filter)是一種用于估計(jì)狀態(tài)的算法,最初由R.E. Kalman在1960年提出。它是一種線性高斯濾波器,常用于處理包含誤差噪聲的動(dòng)態(tài)系統(tǒng)。卡爾曼濾波算法通過(guò)組合測(cè)量
    的頭像 發(fā)表于 01-17 10:51 ?3126次閱讀
    主站蜘蛛池模板: 啪啪网站色大全免费| 精品一区亚洲| 操干| 啪啪免费观看| 首页 亚洲 欧美 制服 丝腿| 亚洲区| 伊人蕉久| 四虎影院在线播放| 人人舔| 黄色大片视频| 11111日本网站| 免费午夜网站| 免费观看高清视频| 超刺激gay腐文h文| 四虎国产精品视频免费看| 免费三级黄色| 成人欧美精品大91在线| 天天拍天天干| 91福利视频网| 美女把尿口扒开让男人桶出水| 亚洲成年网| 龙口护士门91午夜国产在线| 俺来色| 国产呦精品系列在线| 59日本人xxxxxxxxx69| 亚洲综合欧美日本另类激情| 欧美午夜视频在线| ww欧洲ww在线视频看| 久久天天躁狠狠躁夜夜不卡| 在线看一区二区| 天堂在线中文字幕| 韩国精品视频| 人人干人人舔| 亚洲一卡2卡4卡5卡6卡在线99| 亚洲 欧美 日韩 综合| 久久本道综合色狠狠五月| 特一级黄色片| 亚洲一区二区在线| 四虎在线精品| 大学生毛片| 99涩涩|