golangの非同期実装

May 16, 2023 pm 02:18 PM

インターネット技術の継続的な発展に伴い、コンピュータープログラミング言語も常に更新され、改良されています。比較的新しいプログラミング言語である Go 言語 (略して golang) は、その高い同時実行性と優れたメモリ管理により、ますます多くの開発者に好まれています。 golang では、非同期呼び出しの実装は非常に一般的な要件です。この記事では、golang での非同期呼び出しの実装について詳しく説明します。

1. golang の非同期呼び出しの概念

コンピューター プログラムは一般的にコード シーケンスに従って順番に実行されることは誰もが知っていますが、実際のアプリケーション プロセスでは、多くの場合、複数のタスクを実行する必要があります。これを行うとき、非同期呼び出しの概念を導入します。非同期呼び出しは、同時実行の方法です。つまり、プログラムは、各タスクの終了を待たずに、次のタスクを実行する前に複数のタスクを同時に実行します。非同期呼び出しでは、各タスクは個別のスレッドを開始し、タスクの完了後にメインスレッドに戻るため、他のタスクの通常の実行には影響しません。

golang では、非同期呼び出しの実装が他のプログラミング言語とは異なり、goroutine (コルーチン) を使用して非同期呼び出しを実装します。 Goroutine は、プログラム内に複数のコルーチンを作成できる軽量のスレッドで、各コルーチンは独立しており、同時に実行できます。

2. golang で非同期呼び出しを実装する方法

golang では、goroutine とチャネルを使用して非同期呼び出しの機能を実装できます。

  1. ゴルーチンを使用して非同期呼び出しを実装する

golang では、ゴルーチンを開くのは非常に簡単です。関数の前に go キーワードを追加するだけです。例:

go func() {
    // 执行任务的代码
}()
ログイン後にコピー

上記のコードは、新しい goroutine でタスクを実行します。完全なサンプル コードを見てみましょう:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 开启一个goroutine执行任务
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("goroutine执行...", i)
            time.Sleep(1 * time.Second)
        }
    }()

    // 主线程执行任务
    for i := 0; i < 5; i++ {
        fmt.Println("主线程执行...", i)
        time.Sleep(1 * time.Second)
    }

    // 等待一段时间,保证goroutine执行完毕
    time.Sleep(15 * time.Second)
    fmt.Println("程序结束...")
}
ログイン後にコピー

上記のコードを通じて、プログラムが goroutine 実行タスクを開始し、メイン スレッドが同時に別のタスクも実行していることがわかります。プログラムの実行中、メインスレッドとゴルーチンは相互に影響を与えることなく同時に実行できます。

  1. チャネルを使用して非同期呼び出しを実装する

golang では、チャネルはゴルーチン間の通信手段であり、チャネルを使用して非同期呼び出しを実装できます。以下に示すように、バッファーを使用してチャネルを作成し、ゴルーチンでタスクを実行し、その結果をチャネルを通じてメインスレッドに渡すことができます。

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个带缓冲区的channel
    ch := make(chan int, 10)

    // 在goroutine中执行任务,并将结果通过channel传递给主线程
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
    }()

    // 主线程读取channel中的数据
    for {
        num, ok := <-ch
        if ok {
            fmt.Println("收到数据:", num)
        } else {
            break
        }
    }

    fmt.Println("程序结束...")
}
ログイン後にコピー

上記のコードでは、次のコードを使用してチャネルを作成します。バッファのチャネルを取得してゴルーチン内でタスクを実行し、タスクの結果がチャネルを通じてメインスレッドに渡されます。メインスレッドはループを通じてチャネル内のデータを読み取り、チャネルが閉じられると、ok 変数を使用してループが終了するかどうかを判断し、それによってプログラムが正常に終了できるようにします。

3. golang 非同期呼び出しのアプリケーション シナリオ

実際のアプリケーションでは、非同期呼び出しは次のシナリオでよく使用されます:

  1. ネットワーク リクエスト

ネットワーク通信では、ネットワーク状況が不確実であるため、リクエストの応答時間が非常に長くなる可能性があり、同期呼び出しを使用すると、プログラムが長時間ブロックされ、ユーザー エクスペリエンスに影響を与えます。したがって、非同期呼び出しを使用することで、リクエスト後のレスポンスを待つ必要がなく、他のタスクを継続して実行し、レスポンスが到着するまで待ってから処理することができます。

  1. ファイル操作

一部のファイル操作では、ファイル内容の読み取り、ファイルへの書き込みなど、多数の I/O 操作が必要になる場合があります。これらの I/O 操作には時間がかかり、同期呼び出しが使用される場合、プログラムがブロックされ、非効率になる可能性があります。したがって、ファイル操作に時間がかかる場合は、メインスレッドの通常の動作に影響を与えることなく、非同期呼び出しを使用して goroutine を使用してタスクを実行できます。

  1. スケジュールされたタスク

一部のスケジュールされたタスクでは、時間のかかる操作を実行する必要がある場合があります。同期呼び出しを使用すると、プログラムの時間精度や安定性に影響が出る可能性があります。したがって、非同期呼び出しを使用すると、プログラムの精度や安定性に影響を与えることなく、メインスレッドがスケジュールされたタスクを実行している間に、ゴルーチンが特定の操作タスクを実行できるようになります。

4. 結論

非同期呼び出しは、最新のプログラミング言語で非常に一般的なプログラミング手法であり、プログラムの効率と安定性を高めることができます。強力な同時実行性を持つプログラミング言語である golang は、ゴルーチンとチャネルを介した非同期呼び出しをサポートしており、非常に便利で実用的です。実際のアプリケーションでは、プログラムのパフォーマンスとユーザー エクスペリエンスを向上させるために、特定のシナリオに基づいて適切な非同期呼び出し方法を選択する必要があります。

以上がgolangの非同期実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Mar 03, 2025 pm 05:17 PM

この記事では、Goのパッケージインポートメカニズム:名前付きインポート(例:インポート "fmt&quot;)および空白のインポート(例:_&quot; fmt&quot;)について説明しています。 名前付きインポートはパッケージのコンテンツにアクセス可能になり、空白のインポートはtのみを実行します

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? Mar 03, 2025 pm 05:18 PM

この記事では、MySQLクエリの結果をGO structスライスに効率的に変換することを詳しく説明しています。 データベース/SQLのスキャン方法を使用して、手動で解析することを避けて強調しています。 DBタグとロブを使用した構造フィールドマッピングのベストプラクティス

Beegoフレームワークのページ間で短期情報転送を実装する方法は? Beegoフレームワークのページ間で短期情報転送を実装する方法は? Mar 03, 2025 pm 05:22 PM

この記事では、Webアプリケーションでのページ間データ転送のためのBeegoのnewflash()関数について説明します。 newflash()を使用して、コントローラー間で一時的なメッセージ(成功、エラー、警告)を表示し、セッションメカニズムを活用することに焦点を当てています。 リミア

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

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

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? Mar 10, 2025 pm 03:20 PM

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

Go言語でファイルを便利に書く方法は? Go言語でファイルを便利に書く方法は? Mar 03, 2025 pm 05:15 PM

この記事では、goで効率的なファイルの書き込みを詳しく説明し、os.writefile(小さなファイルに適している)とos.openfileおよびbuffered write(大規模ファイルに最適)と比較します。 延期エラー処理、Deferを使用し、特定のエラーをチェックすることを強調します。

Goでユニットテストをどのように書きますか? Goでユニットテストをどのように書きますか? Mar 21, 2025 pm 06:34 PM

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

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? Mar 10, 2025 pm 05:36 PM

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

See all articles