2 回答

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超6個(gè)贊
有沒有更慣用的方法來(lái)進(jìn)行這種計(jì)算?
您實(shí)際上不需要循環(huán)來(lái)計(jì)算它。
如果你使用GCD 函數(shù)(標(biāo)準(zhǔn)庫(kù)的一部分),你會(huì)得到返回的數(shù)字 x 和 y,這樣:
x*P+y*Base=1
這意味著 x 是您想要的答案(因?yàn)?x*P = 1 modulo Base):
package main
import (
? ? "fmt"
? ? "math/big"
)
const (
? ? P? ? = 1000099
? ? Base = 1<<31 - 1
)
func main() {
? ? bigP := big.NewInt(P)
? ? bigBase := big.NewInt(Base)
? ? // Compute inverse of bigP modulo bigBase
? ? bigGcd := big.NewInt(0)
? ? bigX := big.NewInt(0)
? ? bigGcd.GCD(bigX,nil,bigP,bigBase)
? ? // x*bigP+y*bigBase=1?
? ? // => x*bigP = 1 modulo bigBase
? ? fmt.Println(bigX)
}

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊
這是一種糟糕的風(fēng)格,我應(yīng)該有類似的東西嗎
WaitGroup
?
等待組解決了不同的問題。
一般來(lái)說(shuō),要在這里成為一個(gè)負(fù)責(zé)任的 go 公民并確保您的代碼運(yùn)行并在其背后進(jìn)行整理,您可能需要結(jié)合執(zhí)行以下操作:
當(dāng)在別處找到計(jì)算結(jié)果時(shí),向生成的 goroutines 發(fā)出停止計(jì)算的信號(hào)。
確保同步進(jìn)程在返回之前等待 goroutines 停止。如果它們正確響應(yīng)#1 中的信號(hào),這不是強(qiáng)制性的,但如果您不等待,則無(wú)法保證它們?cè)诟?goroutine 繼續(xù)之前已終止。
在執(zhí)行此任務(wù)然后退出的示例程序中,絕對(duì)不需要執(zhí)行任何操作。正如這條評(píng)論所指出的,您的程序的main
方法在找到滿意的答案后終止,此時(shí)程序?qū)⒔Y(jié)束,所有 goroutine 將立即終止,并且操作系統(tǒng)將整理所有消耗的資源。等待 goroutines 停止是不必要的。
但是,如果您將這段代碼打包到一個(gè)庫(kù)中,或者它成為長(zhǎng)期運(yùn)行的“反素?cái)?shù)計(jì)算”服務(wù)的一部分,那么最好整理您生成的 goroutine 以避免不必要地浪費(fèi)周期。此外,一般來(lái)說(shuō),您可能還有其他場(chǎng)景,其中 goroutines 存儲(chǔ)狀態(tài)、持有外部資源的句柄或持有內(nèi)部對(duì)象的句柄,如果沒有妥善整理,您就有泄漏的風(fēng)險(xiǎn)——最好適當(dāng)?shù)仃P(guān)閉這些。
傳達(dá)停止工作的要求
有幾種方法可以傳達(dá)這一點(diǎn)。我不認(rèn)為這是一個(gè)詳盡的清單!(請(qǐng)?jiān)谠u(píng)論中或通過(guò)對(duì)帖子提出編輯建議來(lái)建議其他通用方法。)
使用特殊渠道
通過(guò)關(guān)閉為此目的保留的特殊“關(guān)閉”通道向子 goroutine 發(fā)出信號(hào)。這利用了通道公理:
來(lái)自關(guān)閉通道的接收立即返回零值
從關(guān)閉通道接收后,goroutine 應(yīng)立即安排整理任何本地狀態(tài)并從函數(shù)返回。您之前的問題有實(shí)現(xiàn)此功能的示例代碼;該模式的一個(gè)版本是:
func myGoRoutine(shutdownChan <-chan struct{}) {
select {
case <-shutdownChan:
// tidy up behaviour goes here
return
// You may choose to listen on other channels here to implement
// the primary behaviour of the goroutine.
}
}
func main() {
shutdownChan := make(chan struct{})
go myGoRoutine(shutdownChan)
// some time later
close(shutdownChan)
}
在這種情況下,關(guān)閉邏輯被浪費(fèi)了,因?yàn)樵搈ain()方法將在調(diào)用后立即返回close。這將與 goroutine 的關(guān)閉競(jìng)爭(zhēng),但我們應(yīng)該假設(shè)它不會(huì)正確執(zhí)行其整理行為。第 2 點(diǎn)解決了解決此問題的方法。
使用上下文
該context包提供了創(chuàng)建可以取消的上下文的選項(xiàng)。取消時(shí),上下文Done()方法公開的通道將關(guān)閉,這標(biāo)志著從 goroutine 返回的時(shí)間。
這種方法與之前的方法大致相同,除了更簡(jiǎn)潔的封裝和上下文的可用性以傳遞給 goroutine 中的下游調(diào)用以在需要時(shí)取消嵌套調(diào)用。例子:
func myGoRoutine(ctx context.Context) {
select {
case <-ctx.Done():
// tidy up behaviour goes here
return
// Put real behaviour for the goroutine here.
}
}
func main() {
// Get a context (or use an existing one if you are provided with one
// outside a `main` method:
ctx := context.Background()
// Create a derived context with a cancellation method
ctx, cancel := context.WithCancel(ctx)
go myGoRoutine(ctx)
// Later, when ready to quit
cancel()
}
這與另一種情況有相同的錯(cuò)誤,因?yàn)樵搈ain方法不會(huì)等待子 goroutines 在返回之前退出。
等待(或“加入”)子協(xié)程停止
上面示例中關(guān)閉關(guān)閉通道或關(guān)閉上下文的代碼不會(huì)等待子 goroutine 停止工作再繼續(xù)。這在某些情況下可能是可以接受的,而在其他情況下,您可能需要保證 goroutines 在繼續(xù)之前已經(jīng)停止。
sync.WaitGroup可以用來(lái)實(shí)現(xiàn)這個(gè)要求。文檔很全面。等待組是一個(gè)計(jì)數(shù)器,它應(yīng)該Add在啟動(dòng) goroutine 時(shí)使用它的方法遞增,并Done在 goroutine 完成時(shí)使用它的方法遞減。代碼可以通過(guò)調(diào)用其方法等待計(jì)數(shù)器歸零Wait,該方法會(huì)阻塞直到條件為真。對(duì) 的所有調(diào)用都Add必須在對(duì) 的調(diào)用之前發(fā)生Wait。
示例代碼:
func main() {
var wg sync.WaitGroup
// Increment the WaitGroup with the number of goroutines we're
// spawning.
wg.Add(1)
// It is common to wrap a goroutine in a function which performs
// the decrement on the WaitGroup once the called function returns
// to avoid passing references of this control logic to the
// downstream consumer.
go func() {
// TODO: implement a method to communicate shutdown.
callMyFunction()
wg.Done()
}()
// Indicate shutdown, e.g. by closing a channel or cancelling a
// context.
// Wait for goroutines to stop
wg.Wait()
}
有沒有更慣用的方法來(lái)進(jìn)行這種計(jì)算?
通過(guò)以您定義的方式使用 goroutines,該算法當(dāng)然可以并行化。由于工作受 CPU 限制,goroutines 對(duì)可用 CPU 數(shù)量的限制是有意義的(在機(jī)器上沒有其他工作的情況下)以從可用計(jì)算資源中獲益。
- 2 回答
- 0 關(guān)注
- 133 瀏覽
添加回答
舉報(bào)