php エディタ Xigua は、プログラミング プロセス中にプログラムがハングするという問題によく遭遇します。プログラムのハングとは、プログラムが実行中にエラー メッセージも表示されずに突然応答を停止することを意味します。この状況では、何が問題なのか混乱してしまうことがよくあります。このプログラムがハングするのはなぜでしょうか?この記事では、プログラムがハングする一般的な原因をいくつか調査し、問題の解決に役立つ解決策を提供します。初心者でも経験豊富な開発者でも、これらの内容は役立つと思います。
質問内容
goでチャネル間で通信するコードがあります。やりたいことをやっているように見えますが、最後にハングします。ハングする原因を診断しようとしています。
このコードは、httpbin.org
を使用してランダムな uuid を取得し、セマフォ チャネルとレート チャネルを通じて確立した同時実行性とレート制限を遵守しながら、それを公開します。
package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "sync" "time" ) type HttpBinGetRequest struct { url string } type HttpBinGetResponse struct { Uuid string `json:"uuid"` StatusCode int } type HttpBinPostRequest struct { url string uuid string // Item to post to API } type HttpBinPostResponse struct { Data string `json:"data"` StatusCode int } func main() { // Prepare GET requests for n requests var requests []*HttpBinGetRequest for i := 0; i < 10; i++ { uri := "https://httpbin.org/uuid" request := &HttpBinGetRequest{ url: uri, } requests = append(requests, request) } // Create semaphore and rate limit for the GET endpoint getSemaphore := make(chan struct{}, 10) getRate := make(chan struct{}, 10) defer close(getRate) defer close(getSemaphore) for i := 0; i < cap(getRate); i++ { getRate <- struct{}{} } go func() { // ticker corresponding to 1/nth of a second // where n = rate limit // basically (1000 / rps) * time.Millisecond ticker := time.NewTicker(100 * time.Millisecond) defer ticker.Stop() for range ticker.C { _, ok := <-getRate if !ok { return } } }() // Send our GET requests to obtain a random UUID respChan := make(chan HttpBinGetResponse) var wg sync.WaitGroup for _, request := range requests { wg.Add(1) // cnt := c // Go func to make request and receive the response go func(r *HttpBinGetRequest) { defer wg.Done() // Check the rate limiter and block if it is empty getRate <- struct{}{} // fmt.Printf("Request #%d at: %s\n", cnt, time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")) resp, _ := get(r, getSemaphore) fmt.Printf("%+v\n", resp) // Place our response into the channel respChan <- *resp // fmt.Printf("%+v,%s\n", resp, time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")) }(request) } // Set up for POST requests 10/s postSemaphore := make(chan struct{}, 10) postRate := make(chan struct{}, 10) defer close(postRate) defer close(postSemaphore) for i := 0; i < cap(postRate); i++ { postRate <- struct{}{} } go func() { // ticker corresponding to 1/nth of a second // where n = rate limit // basically (1000 / rps) * time.Millisecond ticker := time.NewTicker(100 * time.Millisecond) defer ticker.Stop() for range ticker.C { _, ok := <-postRate if !ok { return } } }() // Read responses as they become available for ele := range respChan { postReq := &HttpBinPostRequest{ url: "https://httpbin.org/post", uuid: ele.Uuid, } go func(r *HttpBinPostRequest) { postRate <- struct{}{} postResp, err := post(r, postSemaphore) if err != nil { fmt.Println(err) } fmt.Printf("%+v\n", postResp) }(postReq) } wg.Wait() close(respChan) } func get(hbgr *HttpBinGetRequest, sem chan struct{}) (*HttpBinGetResponse, error) { // Add a token to the semaphore sem <- struct{}{} // Remove token when function is complete defer func() { <-sem }() httpResp := &HttpBinGetResponse{} client := &http.Client{} req, err := http.NewRequest("GET", hbgr.url, nil) if err != nil { fmt.Println("error making request") return httpResp, err } req.Header = http.Header{ "accept": {"application/json"}, } resp, err := client.Do(req) if err != nil { fmt.Println(err) fmt.Println("error getting response") return httpResp, err } // Read Response body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println("error reading response body") return httpResp, err } json.Unmarshal(body, &httpResp) httpResp.StatusCode = resp.StatusCode return httpResp, nil } // Method to post data to httpbin func post(hbr *HttpBinPostRequest, sem chan struct{}) (*HttpBinPostResponse, error) { // Add a token to the semaphore sem <- struct{}{} defer func() { <-sem }() httpResp := &HttpBinPostResponse{} client := &http.Client{} req, err := http.NewRequest("POST", hbr.url, bytes.NewBuffer([]byte(hbr.uuid))) if err != nil { fmt.Println("error making request") return httpResp, err } req.Header = http.Header{ "accept": {"application/json"}, } resp, err := client.Do(req) if err != nil { fmt.Println("error getting response") return httpResp, err } // Read Response body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println("error reading response body") return httpResp, err } json.Unmarshal(body, &httpResp) httpResp.StatusCode = resp.StatusCode return httpResp, nil }
回避策
コードの最後にある respchan
から range
ステートメントを介して読み取りを行っています。このコードは、チャネルが閉じられるまで終了しません。これは、このコード ブロックの後に発生します。
したがって、このロジックはすべて同じ goroutine 内にあるため、プログラムは決して終了しません。
プログラムが終了する前にすべてのレコードが確実に処理されるように修正するには、チャネル読み取りコードをメインの goroutine に保持し、待機/クローズ ロジックを独自の goroutine に組み込みます。 リーリー
ループ内の子ゴルーチンの最後の range を待機するように を編集します。おそらく待機グループを使用するよりクリーンな方法がありますが、簡単な解決策は次のとおりです。
リーリー
以上がこのプログラムがハングするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

OpenSSLは、安全な通信で広く使用されているオープンソースライブラリとして、暗号化アルゴリズム、キー、証明書管理機能を提供します。ただし、その歴史的バージョンにはいくつかの既知のセキュリティの脆弱性があり、その一部は非常に有害です。この記事では、Debian SystemsのOpenSSLの共通の脆弱性と対応測定に焦点を当てます。 Debianopensslの既知の脆弱性:OpenSSLは、次のようないくつかの深刻な脆弱性を経験しています。攻撃者は、この脆弱性を、暗号化キーなどを含む、サーバー上の不正な読み取りの敏感な情報に使用できます。

この記事では、プロファイリングの有効化、データの収集、CPUやメモリの問題などの一般的なボトルネックの識別など、GOパフォーマンスを分析するためにPPROFツールを使用する方法について説明します。

この記事では、GOでユニットテストを書くことで、ベストプラクティス、モッキングテクニック、効率的なテスト管理のためのツールについて説明します。

この記事では、ユニットテストのためにGOのモックとスタブを作成することを示しています。 インターフェイスの使用を強調し、模擬実装の例を提供し、模擬フォーカスを維持し、アサーションライブラリを使用するなどのベストプラクティスについて説明します。 articl

この記事では、GENICSのGOのカスタムタイプの制約について説明します。 インターフェイスがジェネリック関数の最小タイプ要件をどのように定義するかを詳しく説明し、タイプの安全性とコードの再利用性を改善します。 この記事では、制限とベストプラクティスについても説明しています

この記事では、コードのランタイム操作に使用されるGoの反射パッケージについて説明します。シリアル化、一般的なプログラミングなどに有益です。実行やメモリの使用量の増加、賢明な使用と最高のアドバイスなどのパフォーマンスコストについて警告します

この記事では、トレースツールを使用してGOアプリケーションの実行フローを分析します。 手動および自動計装技術について説明し、Jaeger、Zipkin、Opentelemetryなどのツールを比較し、効果的なデータの視覚化を強調しています

この記事では、GOでテーブル駆動型のテストを使用して説明します。これは、テストのテーブルを使用して複数の入力と結果を持つ関数をテストする方法です。読みやすさの向上、重複の減少、スケーラビリティ、一貫性、および


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

Dreamweaver Mac版
ビジュアル Web 開発ツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

ドリームウィーバー CS6
ビジュアル Web 開発ツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

ホットトピック



