第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

并發(fā)和復(fù)制的請(qǐng)求,什么是時(shí)間。After() for?

并發(fā)和復(fù)制的請(qǐng)求,什么是時(shí)間。After() for?

Go
侃侃爾雅 2022-08-01 10:30:43
我正在閱讀 Go 中的并發(fā)性,并且非常接近尾聲!總的來(lái)說(shuō),這是一本很棒的讀物。在其中一個(gè)示例中,作者描述了如何模擬請(qǐng)求復(fù)制。代碼示例如下:func main() {    doWork := func(        done <-chan interface{},        id int,        wg *sync.WaitGroup,        result chan<- int,    ) {        started := time.Now()        defer wg.Done()        // Simulate random load        simulatedLoadTime := time.Duration(1*rand.Intn(5)) * time.Second        /** use two separate select blocks because we want to send/receive two different values, the time.After (receive) and the id (send).        / if they were in the same select block, then we could only use one value at a time, the other will get lost. */        select {        // do not want to return on <-done because we still want to log the time it took        case <-done:        case <-time.After(simulatedLoadTime):        }        select {        case <-done:        case result <- id:        }        took := time.Since(started)        // Display how long handlers would have taken        if took < simulatedLoadTime {            took = simulatedLoadTime        }        fmt.Printf("%v took %v\n", id, took)    }    done := make(chan interface{})    result := make(chan int)    var wg sync.WaitGroup    wg.Add(10)    for i := 0; i < 10; i++ {        go doWork(done, i, &wg, result)    }    firstReturned := <-result    close(done)    wg.Wait()    fmt.Printf("Received an answer from #%v\n", firstReturned)}我不明白的一句話是.為什么會(huì)在這里?我們什么時(shí)候會(huì)利用從該通道返回的值。該通道是如何在選擇塊之外進(jìn)行通信的?無(wú)論出于何種原因,這條線似乎在同步結(jié)果的時(shí)間方面都是不可或缺的,因?yàn)槿绻矣胊替換它,結(jié)果就不同步了。case <-time.After(simulatedLoadTime)default:
查看完整描述

1 回答

?
子衿沉夜

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊

這已經(jīng)通過(guò)評(píng)論得到了回答(請(qǐng)參閱mkopriva的評(píng)論),但讓我提供一個(gè)“答案化”版本。

首先,一個(gè)小小的旁白:

done := make(chan interface{})

我通??吹竭@里。由于從未發(fā)送過(guò)任何實(shí)際值,因此通道的類(lèi)型并不重要,但是發(fā)送空值根本不占用空間,而發(fā)送空值則占用空間。1 個(gè)make(chan struct{})structinterface{}

現(xiàn)在,我們?cè)谶@里要做的,在結(jié)束語(yǔ)中,2是:

  • 等待(或至少假裝等待)某個(gè)服務(wù)器應(yīng)答;

  • 如果發(fā)生超時(shí),請(qǐng)停止等待服務(wù)器;和

  • 將我們的ID發(fā)送到結(jié)果渠道

或者如果頻道關(guān)閉(表明其他人打敗我們做任何事情),不要打擾上述任何一項(xiàng)。done

作為一個(gè)復(fù)雜因素,我們還將記錄我們等待了多長(zhǎng)時(shí)間,即使我們沒(méi)有得到答案。

主要功能:

  • 創(chuàng)建通道,其唯一目的是 d,以便從它接收立即返回它們?cè)?EOF 處缺少值的零值;doneclose

  • 剝離這些工人的一些數(shù)字(具體為10);

  • 等待第一個(gè)交付結(jié)果(可能是由于超時(shí),結(jié)果而導(dǎo)致的結(jié)果缺失)

  • 關(guān)閉通道以使其余工作線程終止;和done

  • 打印最終結(jié)果。

我們感興趣的是為什么閉包的代碼是用代碼片段編寫(xiě)的:

  select {    case <-done:    case <-time.After(simulatedLoadTime):
    }

在其中。

這里的訣竅是預(yù)先評(píng)估其所有替代方案。因此,在開(kāi)始選擇過(guò)程之前,它會(huì)評(píng)估通道,但也調(diào)用 。然后,等待具有值或位于通道末端并因此具有EOF的任何一個(gè),以先發(fā)生者為準(zhǔn)。selectdonetime.After()select

如果還沒(méi)有戈魯廷將結(jié)果發(fā)送回主戈魯廷,則該通道將不會(huì)關(guān)閉。此時(shí),所有 goroutines 都將阻塞在通道上。但是所有的戈魯丁人也會(huì)叫.donedonetime.After

該代碼啟動(dòng)一個(gè) goroutine,經(jīng)過(guò)一段時(shí)間后,它將在通道上發(fā)送當(dāng)前時(shí)間。然后,它返回該通道。因此,這兩個(gè)操作中至少有一個(gè)將完成:通道將關(guān)閉或 get 關(guān)閉,并且由于 EOF,我們將在其上獲得零值,或者返回的通道將有一個(gè)時(shí)間發(fā)送到它,我們將收到該值。無(wú)論我們實(shí)際獲得哪個(gè)值,我們都會(huì)將值放在地板上,但是兩個(gè)運(yùn)算符中的一個(gè)最終會(huì)解除阻塞的事實(shí)保證了這個(gè)goroutine最終能夠繼續(xù)。time.After<-donetime.After<-

首先發(fā)生的事件將是通道的關(guān)閉或時(shí)間的接收。我們不知道這是哪一個(gè),因?yàn)槲覀儾恢劳ǖ狸P(guān)閉需要多長(zhǎng)時(shí)間,但是時(shí)間的上限是我們傳遞給的持續(xù)時(shí)間有多長(zhǎng)。也就是說(shuō),要么發(fā)生(最終),要么在我們選擇的時(shí)間之后,部分發(fā)生。其中之一肯定會(huì)發(fā)生。donedonetime.Afterdonetime.After

現(xiàn)在,如果我們不關(guān)心記錄我們花費(fèi)的時(shí)間,我們可以把它寫(xiě)成:

    select {    case <-done:        return
    case <-time.After(simulatedLoadTime):        // everything else happens here
    }

但請(qǐng)注意原始代碼中的注釋?zhuān)?/p>

// do not want to return on <-done because we still want to log ...

因此,這解釋了缺乏.return

超時(shí)后,我們現(xiàn)在必須嘗試將我們的ID發(fā)送到主goroutine。但是,我們可能無(wú)法做到這一點(diǎn):其他一些工作 goroutine 可能會(huì)擊敗我們發(fā)送,而主 goroutine 僅從通道讀取一個(gè)值。為了確保我們不會(huì)被困在這里,我們還有另一個(gè).我們將嘗試發(fā)送我們的 ID,但如果頻道現(xiàn)在關(guān)閉或關(guān)閉,則停止。然后,我們將記錄并返回。selectdone


1 個(gè)我一直認(rèn)為Go應(yīng)該有一個(gè)預(yù)先聲明的空結(jié)構(gòu)類(lèi)型,只是為了方便和風(fēng)格的東西。我們?cè)谶@里將其用于我們的頻道。我們將它用于僅作為集合而存在的映射,除了它們還將具有預(yù)先聲明的僅方便和樣式類(lèi)型。但這完全是另一回事。done

阿拉伯?dāng)?shù)字這里沒(méi)有特別好的理由使用閉包。未導(dǎo)出的普通函數(shù)也可以正常工作。假設(shè)我們使用的是閉包,我們可以捕獲通道、值和通道,而不是將它們作為參數(shù)。我不清楚為什么作者選擇把它寫(xiě)成一個(gè)可能成為函數(shù)的閉包,然后不去打擾閉包給我們帶來(lái)的任何好東西。donewg *WaitGroupresult


查看完整回答
反對(duì) 回復(fù) 2022-08-01
  • 1 回答
  • 0 關(guān)注
  • 111 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)