를 사용한 비동기 프로그래밍 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 메서드의 비동기 버전은 다음 인수를 허용합니다.

  • 동기식 객체와 동일한 요청 유형 객체에 대한 참조입니다.

  • 응답 핸들러 콜백 함수에 대한 참조입니다. 이 콜백 함수는 비동기 작업이 완료되면 호출됩니다. 인수 중 하나에는 작업의 결과가 포함됩니다.

  • 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 메서드는 uploadFileAsync 메서드에서 S3Client 객체를 생성하고 로컬 변수에 저장하는 대신 및 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(); }

비동기 작업이 완료되면 연결된 리소스를 릴리스할 수 있습니다. 원하는 경우 애플리케이션을 종료할 수도 있습니다.

다음 코드는 애플리케이션에서 uploadFileAsyncuploadFileAsyncFinished 메서드를 사용하는 방법을 보여줍니다.

애플리케이션은 비동기 작업이 완료될 때까지 계속 존재하도록 S3ClientPutObjectRequest 객체를 할당합니다. 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의 전체 예제를 참조하십시오.