Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Programmazione asincrona mediante AWS SDK per C++
metodi SDK asincroni
Per molti metodi, l'SDK for C++ fornisce versioni sia sincrone che asincrone. Un metodo è asincrono se include il suffisso nel nome. Async Ad esempio, il metodo Amazon S3 è sincrono, mentre PutObject PutObjectAsync è asincrono.
Come tutte le operazioni asincrone, un metodo SDK asincrono viene restituito prima del termine dell'attività principale. Ad esempio, il PutObjectAsync metodo restituisce prima del completamento del caricamento del file nel bucket Amazon S3. Mentre l'operazione di caricamento continua, l'applicazione può eseguire altre operazioni, inclusa la chiamata di altri metodi asincroni. L'applicazione viene informata che un'operazione asincrona è terminata quando viene richiamata una funzione di callback associata.
Le sezioni seguenti descrivono un esempio di codice che dimostra la chiamata al metodo asincrono. PutObjectAsync Ogni sezione si concentra su singole parti dell'intero file sorgente dell'esempio.
Chiamata di metodi asincroni SDK
In generale, la versione asincrona di un metodo SDK accetta i seguenti argomenti.
-
Un riferimento allo stesso oggetto di tipo Request-type della sua controparte sincrona.
-
Un riferimento a una funzione di callback del gestore di risposte. Questa funzione di callback viene richiamata al termine dell'operazione asincrona. Uno degli argomenti contiene il risultato dell'operazione.
-
Opzionale
shared_ptrper unAsyncCallerContextoggetto. L'oggetto viene passato al callback del gestore di risposte. Include una proprietà UUID che può essere utilizzata per passare informazioni di testo al callback.
Il uploadFileAsync metodo illustrato di seguito configura e chiama il metodo Amazon PutObjectAsync S3 dell'SDK per caricare in modo asincrono un file su un bucket Amazon S3.
La funzione riceve riferimenti a un oggetto e a un oggetto. S3Client PutObjectRequest Li riceve dalla funzione principale perché dobbiamo assicurarci che questi oggetti esistano per tutta la durata delle chiamate asincrone.
A shared_ptr a un AsyncCallerContext oggetto viene assegnato. UUIDLa sua proprietà è impostata sul nome dell'oggetto Amazon S3. A scopo dimostrativo, il callback del gestore di risposte accede alla proprietà e ne restituisce il valore.
La chiamata a PutObjectAsync include un argomento di riferimento alla funzione di callback del gestore della risposta. uploadFileAsyncFinished Questa funzione di callback viene esaminata più dettagliatamente nella sezione successiva.
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; }
Le risorse per un'operazione asincrona devono esistere fino al termine dell'operazione. Ad esempio, gli oggetti client e request devono esistere fino a quando l'applicazione non riceve la notifica del completamento dell'operazione. L'applicazione stessa non può terminare fino al completamento dell'operazione asincrona.
Per questo motivo, il uploadFileAsync metodo accetta riferimenti a PutObjectRequest oggetti S3Client e anziché crearli nel uploadFileAsync metodo e memorizzarli in una variabile locale.
Nell'esempio, il PutObjectAsync metodo ritorna al chiamante immediatamente dopo l'inizio dell'operazione asincrona, consentendo alla catena di chiamata di eseguire attività aggiuntive mentre è in corso l'operazione di caricamento.
Se il client fosse memorizzato in una variabile locale del uploadFileAsync metodo, non rientrerebbe nell'ambito di applicazione al momento della restituzione del metodo. Tuttavia, l'oggetto client deve continuare a esistere fino al termine dell'operazione asincrona.
Notifica del completamento di un'operazione asincrona
Al termine di un'operazione asincrona, viene richiamata una funzione di callback del gestore della risposta dell'applicazione. Questa notifica include l'esito dell'operazione. Il risultato è contenuto nella stessa classe di tipo Outcome restituita dalla controparte sincrona del metodo. Nell'esempio di codice, il risultato è in un oggetto. PutObjectOutcome
La funzione di callback del gestore di risposte dell'esempio uploadFileAsyncFinished è mostrata di seguito. Verifica se l'operazione asincrona è riuscita o fallita. Utilizza a std::condition_variable per notificare al thread dell'applicazione che l'operazione asincrona è terminata.
// 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(); }
Al termine dell'operazione asincrona, le risorse ad essa associate possono essere rilasciate. L'applicazione può anche terminare se lo desidera.
Il codice seguente mostra come i uploadFileAsyncFinished metodi uploadFileAsync and vengono utilizzati da un'applicazione.
L'applicazione alloca gli PutObjectRequest oggetti S3Client and in modo che continuino a esistere fino al termine dell'operazione asincrona. Dopo la chiamatauploadFileAsync, l'applicazione può eseguire tutte le operazioni desiderate. Per semplicità, nell'esempio viene utilizzato un comando std::mutex and std::condition_variable to wait che il callback del gestore di risposta lo informi che l'operazione di caricamento è terminata.
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; }
Vedi l'esempio completo