ホームページ よくある問題 Go言語で同時実行制御を実装する方法

Go言語で同時実行制御を実装する方法

Jun 08, 2023 pm 02:20 PM
同時実行制御に行く

Go 言語で同時実行制御を実装する方法: 1. WaitGroup、複数のゴルーチンのタスク処理に依存関係または結合関係があります; 2. チャネル、ゴルーチンをアクティブにキャンセルでき、複数のゴルーチンでデータを転送できます。 WaitGroup の作業、Context の機能との出会い、3. コンテキスト、メタデータ伝播、信号伝播のキャンセル、タイムアウト制御などを含む、マルチレベル グルーチン間の信号伝播。

Go言語で同時実行制御を実装する方法

#この記事の動作環境: Windows 10 システム、go1.20 バージョン、dell g3 コンピューター。

Golang では、go キーワードを使用して goroutine を開くことができるため、Go で同時実行コードを簡単に作成できます。しかし、これらの同時実行グルーチンを効果的に制御するにはどうすればよいでしょうか?

同時実行制御というと、多くの人は最初にロックを思い浮かべるかもしれません。 Golang は、ミューテックス ロック sync.Mutex や読み取り/書き込みロック sync.RWMutex などのロック関連のメカニズムも提供します。ロックに加えて、同期/アトミックなどのアトミック操作もあります。ただし、これらのメカニズムの焦点は、ゴルーチンの同時データの安全性にあります。この記事で議論したいのは、ゴルーチンの同時実行動作制御です。

ゴルーチンの同時動作制御には、WaitGroup、channel、Context という 3 つの一般的なメソッドがあります。

WaitGroup

WaitGroup は sync パッケージ配下にあり、使い方は以下の通りです。

func main() {
  var wg sync.WaitGroup

  wg.Add(2) //添加需要完成的工作量2

  go func() {
    wg.Done() //完成工作量1
    fmt.Println("goroutine 1 完成工作!")
  }()

  go func() {
    wg.Done() //完成工作量1
    fmt.Println("goroutine 2 完成工作!")
  }()

  wg.Wait() //等待工作量2均完成
  fmt.Println("所有的goroutine均已完成工作!")}输出:
//goroutine 2 完成工作!
//goroutine 1 完成工作!
//所有的goroutine均已完成工作!
ログイン後にコピー

WaitGroup この同時実行制御メソッドは、次の場合に特に適しています: タスクで複数の goroutine が連携する必要がある場合、各 goroutine はタスクの一部しか実行できない場合、タスクはすべての goroutine が完了した場合にのみ完了します。したがって、WaitGroup はその名前と同じ意味で、待機方法です。

しかし、実際のビジネスでは、特定の要件が満たされた場合、特定のゴルーチンの終了を能動的に通知する必要があるというシナリオがあります。たとえば、バックグラウンド監視ゴルーチンを開始した場合、監視が必要なくなったら、監視ゴルーチンに終了するように通知する必要があります。そうしないと、アイドル状態が続き、リークが発生します。

Channel

上記のシナリオでは、WaitGroup は何もできません。考えられる最も単純な方法: グローバル変数を定義し、この変数を他の場所で変更することで通知する バックグラウンドのゴルーチンは常にこの変数をチェックし、変数が変更されたことが判明した場合は、自動的に閉じます。方法はやや面倒で不器用です。この場合、チャンネル選択が役に立ちます。

func main() {
  exit := make(chan bool)

  go func() {
    for {
      select {
      case <-exit:
        fmt.Println("退出监控")
        return
      default:
        fmt.Println("监控中")
        time.Sleep(2 * time.Second)
      }
    }
  }()

  time.Sleep(5 * time.Second)
  fmt.Println("通知监控退出")
  exit <- true

  //防止main goroutine过早退出
  time.Sleep(5 * time.Second)}输出:
//监控中
//监控中
//监控中
//通知监控退出
//退出监控
ログイン後にコピー

このチャネル選択の組み合わせは、ゴルーチンに終了を通知するより洗練された方法です。

ただし、このソリューションにも限界があります。想像してみてください。複数の goroutine があり、それらをすべて終了するために制御する必要がある場合はどうなるでしょうか?これらのゴルーチンが他のゴルーチンを生成したらどうなるでしょうか?もちろん、この問題を解決するために多くのチャネルを定義できますが、ゴルーチンの関係チェーンにより、このシナリオは複雑になります。

コンテキスト

上記のシナリオは、CS アーキテクチャ モデルでは一般的です。 Go では、一連のリクエストを処理するためにクライアントごとに個別のゴルーチン (A) が開かれることが多く、多くの場合、単一の A が他のサービスもリクエストし (別のゴルーチン B を開始する)、B が別のゴルーチンをリクエストすることもあります。次に、リクエストをデータベースなどのサーバーに送信します。クライアントが切断されたとき、それに関連付けられている A、B、および C は、システムが A、B、および C によって占有されていたリソースを再利用する直前に終了する必要があると想像してください。 A を終了するのは簡単ですが、B と C にも終了するように通知するにはどうすればよいでしょうか?

このとき、Context が表示されます。

func A(ctx context.Context, name string)  {
  go B(ctx ,name) //A调用了B  for {
    select {
    case <-ctx.Done():
      fmt.Println(name, "A退出")
      return
    default:
      fmt.Println(name, "A do something")
      time.Sleep(2 * time.Second)
    }
  }}func B(ctx context.Context, name string)  {
  for {
    select {
    case <-ctx.Done():
      fmt.Println(name, "B退出")
      return
    default:
      fmt.Println(name, "B do something")
      time.Sleep(2 * time.Second)
    }
  }}func main() {
  ctx, cancel := context.WithCancel(context.Background())

  go A(ctx, "【请求1】") //模拟client来了1个连接请求

  time.Sleep(3 * time.Second)
  fmt.Println("client断开连接,通知对应处理client请求的A,B退出")
  cancel() //假设满足某条件client断开了连接,那么就传播取消信号,ctx.Done()中得到取消信号

  time.Sleep(3 * time.Second)}输出:
//【请求1】 A do something
//【请求1】 B do something
//【请求1】 A do something
//【请求1】 B do something
//client断开连接,通知对应处理client请求的A,B退出
//【请求1】 B退出
//【请求1】 A退出
ログイン後にコピー

この例では、クライアントからの接続リクエストがシミュレートされ、それに応じてゴルーチン A が開かれて処理されます。A は B の処理も有効にします。A と B は両方とも追跡に Context を使用します。cancel 関数を使用する場合キャンセルを通知するには、これら 2 つのゴルーチンが終了されます。

これは、コンテキストの制御機能です。コントローラーのようなものです。スイッチを押すと、このコンテキストに基づく、またはコンテキストから派生したすべてのサブコンテキストが通知を受け取ります。このとき、クリーンアップ操作を実行できます。最後に、起動後に制御できない goroutine の問題をエレガントに解決する goroutine をリリースします。

Context の詳しい使用方法については、この記事の範囲を超えています。 Context パッケージについて詳しく説明するフォローアップ記事がある予定ですので、楽しみにお待ちください。

概要

この記事では、Golang の 3 つの同時実行動作制御モードをリストします。モード間に良いか悪いかの区別はなく、異なるシナリオに適切なソリューションを使用するかどうかに依存します。実際のプロジェクトでは、複数の手法を組み合わせて使用​​することがよくあります。

  • WaitGroup: 複数のゴルーチンのタスク処理間に依存関係または結合関係があります。
  • チャネル選択: goroutine をアクティブにキャンセルできます; 複数の groutine でのデータ転送; チャネルは WaitGroup の作業を置き換えることができますが、コード ロジックの複雑さが増加します; 複数のチャネルで Context の機能を満たすことができ、同様に、コードロジックも複雑になります。
  • コンテキスト: マルチレベル グルーチン間の信号伝播 (メタデータ伝播、信号伝播のキャンセル、タイムアウト制御などを含む)。

Golang では、go キーワードを使用して goroutine を開くことができるため、Go で同時実行コードを簡単に作成できます。しかし、これらの同時実行グルーチンを効果的に制御するにはどうすればよいでしょうか?

同時実行制御というと、多くの人は最初にロックを思い浮かべるかもしれません。 Golang は、ミューテックス ロック sync.Mutex や読み取り/書き込みロック sync.RWMutex などのロック関連のメカニズムも提供します。ロックに加えて、同期/アトミックなどのアトミック操作もあります。ただし、これらのメカニズムの焦点は、ゴルーチンの同時データの安全性にあります。この記事で議論したいのは、ゴルーチンの同時実行動作制御です。

ゴルーチンの同時動作制御には、WaitGroup、channel、Context という 3 つの一般的なメソッドがあります。

以上がGo言語で同時実行制御を実装する方法の詳細内容です。詳細については、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)

詳細な検索Deepseek公式ウェブサイトの入り口 詳細な検索Deepseek公式ウェブサイトの入り口 Mar 12, 2025 pm 01:33 PM

2025年の初めに、国内のAI「Deepseek」が驚くべきデビューを果たしました!この無料のオープンソースAIモデルは、OpenAIのO1の公式バージョンに匹敵するパフォーマンスを備えており、Webサイド、アプリ、APIで完全に起動され、iOS、Android、およびWebバージョンのマルチターミナル使用をサポートしています。 DeepSeekの公式Webサイトおよび使用ガイドの詳細な検索:公式Webサイトアドレス:https://www.deepseek.com/sing for webバージョンの手順:上記のリンクをクリックして、DeepSeekの公式Webサイトを入力します。ホームページの[会話の開始]ボタンをクリックします。最初に使用するには、携帯電話検証コードでログインする必要があります。ログインした後、ダイアログインターフェイスを入力できます。 DeepSeekは強力で、コードを書き、ファイルを読み取り、コードを作成できます

Deepseek Webバージョンの公式入り口 Deepseek Webバージョンの公式入り口 Mar 12, 2025 pm 01:42 PM

国内のAI Dark Horse Deepseekは強く上昇し、世界のAI業界に衝撃を与えました! 1年半しか設立されていないこの中国の人工知能会社は、無料でオープンソースのモックアップであるDeepseek-V3とDeepseek-R1で世界的なユーザーから広く称賛されています。 Deepseek-R1は完全に発売され、パフォーマンスはOpenAio1の公式バージョンに匹敵します! Webページ、アプリ、APIインターフェイスで強力な機能を体験できます。ダウンロード方法:iOSおよびAndroidシステムをサポートすると、ユーザーはApp Storeを介してダウンロードできます。 Deepseek Webバージョン公式入り口:HT

deepseekの忙しいサーバーの問題を解決する方法 deepseekの忙しいサーバーの問題を解決する方法 Mar 12, 2025 pm 01:39 PM

DeepSeek:サーバーに混雑している人気のあるAIを扱う方法は? 2025年のホットAIとして、Deepseekは無料でオープンソースであり、OpenAio1の公式バージョンに匹敵するパフォーマンスを備えており、その人気を示しています。ただし、高い並行性は、サーバーの忙しさの問題ももたらします。この記事では、理由を分析し、対処戦略を提供します。 Deepseek Webバージョンの入り口:https://www.deepseek.com/deepseekサーバーに忙しい理由:高い並行アクセス:Deepseekの無料で強力な機能が同時に使用する多数のユーザーを引き付け、サーバーの負荷が過剰になります。サイバー攻撃:Deepseekが米国の金融産業に影響を与えることが報告されています。