を使用した非同期プログラミング AWS SDK for C++ - AWS SDK for C++

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

を使用した非同期プログラミング AWS SDK for C++

非同期 SDK メソッド

多くのメソッドで、 SDK for C++ は同期バージョンと非同期バージョンの両方を提供します。メソッドの名前にAsyncサフィックスが含まれている場合、メソッドは非同期です。例えば、Amazon S3 メソッドPutObjectは同期ですが、 PutObjectAsyncは非同期です。

すべての非同期オペレーションと同様に、非同期 SDK メソッドは、メインタスクが終了する前に を返します。たとえば、 PutObjectAsyncメソッドは、Amazon S3 バケットへのファイルのアップロードが完了する前に を返します。アップロードオペレーションが続行されている間、アプリケーションは他の非同期メソッドの呼び出しなど、他のオペレーションを実行できます。関連付けられたコールバック関数が呼び出されると、非同期オペレーションが完了したことがアプリケーションに通知されます。

以下のセクションでは、PutObjectAsync非同期メソッドの呼び出しを示すコード例について説明します。各セクションでは、例のソースファイル全体の個々の部分に焦点を当てています。

SDK 非同期メソッドの呼び出し

一般に、 SDK メソッドの非同期バージョンは、次の引数を受け入れます。

  • 同期オブジェクトと同じ Request-type オブジェクトへの参照。

  • レスポンスハンドラーコールバック関数への参照。このコールバック関数は、非同期オペレーションが終了すると呼び出されます。引数の 1 つに、オペレーションの結果が含まれます。

  • AsyncCallerContext オブジェクトshared_ptrのオプションの 。オブジェクトはレスポンスハンドラーのコールバックに渡されます。これには、テキスト情報をコールバックに渡すために使用できる UUID プロパティが含まれています。

以下に示すuploadFileAsync方法では、 をセットアップし、SDK の Amazon S3 PutObjectAsyncメソッドを呼び出して、ファイルを Amazon S3 バケットに非同期的にアップロードします。

関数は、 S3Client オブジェクトと PutObjectRequest オブジェクトへの参照を受け取ります。非同期呼び出しの期間中、これらのオブジェクトが存在することを確認する必要があるため、メイン関数からそれらを受け取ります。

AsyncCallerContext オブジェクトshared_ptrへの が割り当てられます。そのUUIDプロパティは Amazon S3 オブジェクト名に設定されます。デモンストレーションの目的で、レスポンスハンドラーのコールバックは プロパティにアクセスし、その値を出力します。

への呼び出しには、レスポンスハンドラーコールバック関数 への参照引数PutObjectAsyncが含まれますuploadFileAsyncFinished。このコールバック関数については、次のセクションで詳しく説明します。

bool AwsDoc::S3::uploadFileAsync(const Aws::S3::S3Client &s3Client, Aws::S3::Model::PutObjectRequest &request, const Aws::String &bucketName, const Aws::String &fileName) { request.SetBucket(bucketName); request.SetKey(fileName); const std::shared_ptr<Aws::IOStream> input_data = Aws::MakeShared<Aws::FStream>("SampleAllocationTag", fileName.c_str(), std::ios_base::in | std::ios_base::binary); if (!*input_data) { std::cerr << "Error: unable to open file " << fileName << std::endl; return false; } request.SetBody(input_data); // Create and configure the context for the asynchronous put object request. std::shared_ptr<Aws::Client::AsyncCallerContext> context = Aws::MakeShared<Aws::Client::AsyncCallerContext>("PutObjectAllocationTag"); context->SetUUID(fileName); // Make the asynchronous put object call. Queue the request into a // thread executor and call the uploadFileAsyncFinished function when the // operation has finished. s3Client.PutObjectAsync(request, uploadFileAsyncFinished, context); return true; }

非同期オペレーションのリソースは、オペレーションが完了するまで存在する必要があります。たとえば、クライアントオブジェクトとリクエストオブジェクトは、アプリケーションがオペレーションが完了したという通知を受け取るまで存在する必要があります。アプリケーション自体は、非同期オペレーションが完了するまで終了できません。

このため、 uploadFileAsyncメソッドは、 S3Client uploadFileAsyncメソッドで作成してローカル変数に保存せずに、 および PutObjectRequest オブジェクトへの参照を受け入れます。

この例では、 PutObjectAsyncメソッドは非同期オペレーションの開始直後に呼び出し元に戻り、呼び出しチェーンがアップロードオペレーションの進行中に追加のタスクを実行できるようにします。

クライアントが uploadFileAsyncメソッドのローカル変数に保存されていた場合、メソッドが返すと範囲外になります。ただし、クライアントオブジェクトは、非同期オペレーションが完了するまで存在し続ける必要があります。

非同期オペレーションの完了の通知

非同期オペレーションが終了すると、アプリケーションレスポンスハンドラーのコールバック関数が呼び出されます。この通知には、オペレーションの結果が含まれます。結果は、メソッドの同期カウンターパートによって返されるのと同じ結果型クラスに含まれます。コード例では、結果は PutObjectOutcome オブジェクトにあります。

レスポンスハンドラーのコールバック関数の例uploadFileAsyncFinishedを以下に示します。非同期オペレーションが成功したか失敗したかをチェックします。を使用してstd::condition_variable、非同期オペレーションが終了したことをアプリケーションスレッドに通知します。

// A mutex is a synchronization primitive that can be used to protect shared // data from being simultaneously accessed by multiple threads. std::mutex AwsDoc::S3::upload_mutex; // A condition_variable is a synchronization primitive that can be used to // block a thread, or to block multiple threads at the same time. // The thread is blocked until another thread both modifies a shared // variable (the condition) and notifies the condition_variable. std::condition_variable AwsDoc::S3::upload_variable;
void uploadFileAsyncFinished(const Aws::S3::S3Client *s3Client, const Aws::S3::Model::PutObjectRequest &request, const Aws::S3::Model::PutObjectOutcome &outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &context) { if (outcome.IsSuccess()) { std::cout << "Success: uploadFileAsyncFinished: Finished uploading '" << context->GetUUID() << "'." << std::endl; } else { std::cerr << "Error: uploadFileAsyncFinished: " << outcome.GetError().GetMessage() << std::endl; } // Unblock the thread that is waiting for this function to complete. AwsDoc::S3::upload_variable.notify_one(); }

非同期オペレーションが完了すると、それに関連付けられたリソースを解放できます。アプリケーションは、必要に応じて終了することもできます。

次のコードは、 uploadFileAsyncおよび uploadFileAsyncFinishedメソッドがアプリケーションでどのように使用されるかを示しています。

アプリケーションは S3Clientおよび PutObjectRequest オブジェクトを割り当てて、非同期オペレーションが完了するまで存在し続けます。を呼び出すとuploadFileAsync、アプリケーションは必要な操作を実行できます。わかりやすくするために、この例では std::mutexと を使用してstd::condition_variable、レスポンスハンドラーのコールバックがアップロードオペレーションが完了したことを通知するまで待機します。

int main(int argc, char* argv[]) { if (argc != 3) { std::cout << R"( Usage: run_put_object_async <file_name> <bucket_name> Where: file_name - The name of the file to upload. bucket_name - The name of the bucket to upload the object to. )" << std::endl; return 1; } const Aws::SDKOptions options; Aws::InitAPI(options); { const Aws::String fileName = argv[1]; const Aws::String bucketName = argv[2]; // A unique_lock is a general-purpose mutex ownership wrapper allowing // deferred locking, time-constrained attempts at locking, recursive // locking, transfer of lock ownership, and use with // condition variables. std::unique_lock<std::mutex> lock(AwsDoc::S3::upload_mutex); // Create and configure the Amazon S3 client. // This client must be declared here, as this client must exist // until the put object operation finishes. const Aws::S3::S3ClientConfiguration config; // Optional: Set to the AWS Region in which the bucket was created (overrides config file). // config.region = "us-east-1"; const Aws::S3::S3Client s3Client(config); // Create the request object. // This request object must be declared here, because the object must exist // until the put object operation finishes. Aws::S3::Model::PutObjectRequest request; AwsDoc::S3::uploadFileAsync(s3Client, request, bucketName, fileName); std::cout << "main: Waiting for file upload attempt..." << std::endl << std::endl; // While the put object operation attempt is in progress, // you can perform other tasks. // This example simply blocks until the put object operation // attempt finishes. AwsDoc::S3::upload_variable.wait(lock); std::cout << std::endl << "main: File upload attempt completed." << std::endl; } Aws::ShutdownAPI(options); return 0; }

GitHub で完全な例をご覧ください。