多分、マルチスレッド・プログラムを扱っていないPHP開発者がゴーランとチャネルを学び始めるでしょう。golangチャンネルを理解する。すべてのゴルーチンが眠っている - デッドロック[ツアー・オブ・ゴー・クローラー]
私は私が私のクロール方法 、しかしできるだけ簡単なコードを記述しようとしている、囲碁のツアーの最後の練習に[Exercise: Web Crawler](私はこの1つ前に他の演習で問題はなかった)
よ次のようになります。
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.Crawl(0xf37c1, 0x12, 0x4, 0x1600e0, 0x104401c0, 0x104000f0)
/tmp/sandbox452918312/main.go:64 +0x80
main.main()
/tmp/sandbox452918312/main.go:87 +0x60
:
func Crawl(url string, depth int, fetcher Fetcher) {
// kick off crawling by passing initial Url to a Job queue
Queue <- Job{
url,
depth,
}
// make sure we close the Queue channel
defer close(Queue)
// read from the Queue
for job := range Queue {
// if fetched or has hit the bottom of depth,
// just continue right away to pick up next Job
if fetched.Has(job.Url) || job.Depth <= 0 {
continue
}
fres := fetcher.Fetch(job.Url)
fetched.Add(job.Url, fres)
for i := range fres.Urls {
// send new urls just fetched from current url in Job
// to the Queue
Queue <- Job{
fres.Urls[i], job.Depth - 1,
}
}
}
for _, res := range fetched.m {
fmt.Println(res)
}
}
go run
は私がどんなgo
コードを書くとPHP
に戻って得るべきではないと言います
もちろん、私はこの問題を探究しており、結論は通常「あなたの肌を閉じます」と言いました。
私はここで何が欠けているのか誰かが指摘できますか?
完全なコードはここにある:https://play.golang.org/p/-98SdVndD6
この演習のための最も慣用golangの方法は何ですか?私はそれらの少数を見つけた。など
一つはあなたにきれいな解決策になると思われますか?
また、チャネルを使用すると、とゴルーチンが必要ですか?
が、バッファリングされていないチャンネルをデッドロック対応する受信が完了するまでブロックします。ジョブを 'Queue'チャンネルで送信すると、そのオブジェクトを受信するのを待ちます。これは、同じ機能で後で受信しようとするために起こることはありません。チャンネルの詳細については、https://golang.org/doc/effective_go.html#channelsをご覧ください。 –