6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS SDK for C++をマルチスレッドで利用する際の注意点

Posted at

AWS SDK for C++をマルチスレッドで利用する場合、Aws::InitAPIAws::ShutdownAPI の呼び出しタイミングでハマったのでメモ。

環境準備

DockerとMinioを利用して開発環境を用意しています。

下記記事の設定や実装をベースにしています。

DockerとMinioでAWS SDK for C++の開発環境を構築する - Qiita
https://qiita.com/kai_kou/items/d160948553504848d380

検証

シングルスレッドで実行

シングルスレッドで実行してみます。main.cppmain メソッドを以下のように変更します。

main.cpp
()

int main()
{
    // シングルスレッドで実行
    put_object("hoge1.txt");
    put_object("hoge2.txt");

    return 0;
}
コンテナ内
# cd /cpp-dev/build
# cmake ..
# cmake --build .
# ./main
hoge1.txt Done!
hoge2.txt Done!

問題なく実行できました。
Minioが利用するディレクトリにファイルが保存されたのも確認できます。

> tree data/hoge
data/hoge/
├── hoge1.txt
└── hoge2.txt
> cat data/hoge/hoge1.txt
hoge!

マルチスレッドで実行

main.cppmain メソッドでマルチスレッド実行するように変更して実行してみます。

main.cpp
()

int main()
{
  // マルチスレッドで実行
  std::thread th_1(put_object, "hoge3.txt");
  std::thread th_2(put_object, "hoge4.txt");
  th_1.join();
  th_2.join();

  return 0;
}
コンテナ内
# cmake --build .
# ./main
hoge3.txt Done!
main: /aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp:55: 
void Aws::Monitoring::OnRequestSucceeded(
  const String&, const String&,
  const std::shared_ptr<const Aws::Http::HttpRequest>&,
  const HttpResponseOutcome&,
  const Aws::Monitoring::CoreMetricsCollection&,
  Aws::Vector<void*>&
): Assertion `s_monitors' failed.
Aborted

1つめは実行されて、2つめがエラーになりました。
Assertion s_monitors' failed. あたりで調べてみると、Aws::InitAPIAws::ShutdownAPI` の実行タイミングに問題がありそうでした。

How to handle Aws::ShutdownAPI with multiple threads on Windows? · Issue #1050 · aws/aws-sdk-cpp
https://github.com/aws/aws-sdk-cpp/issues/1050

c++ - Why does an assert(s_monitors) in MonitoringManager::OnRequestSucceeded() fail? - Stack Overflow
https://stackoverflow.com/questions/54290073/why-does-an-asserts-monitors-in-monitoringmanageronrequestsucceeded-fail

InitAPIPutObjectShutdownAPI の実行後にログを仕込んてみるとPutObject 実行時に落ちてるみたいです。マルチスレッドなので、hoge3.txthoge4.txt の実行タイミングが入れ替わることもあります。

# ./main
hoge3.txt InitAPI
hoge4.txt InitAPI
hoge3.txt PutObject
hoge3.txt Done!
hoge3.txt ShutdownAPI
main: /aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp:55:
void Aws::Monitoring::OnRequestSucceeded(
  const String&, const String&,
  const std::shared_ptr<const Aws::Http::HttpRequest>&,
  const HttpResponseOutcome&,
  const Aws::Monitoring::CoreMetricsCollection&,
  Aws::Vector<void*>&
): Assertion `s_monitors' failed.
Aborted

原因と解決策

おそらくですが、Aws::InitAPIAws::ShutdownAPI がグローバルな初期化関数とクリーンアップ機能なので、マルチスレッドスレッド中に呼び出すとダメっぽいです。

なので、put_object メソッド内で呼び出しているAws::InitAPIAws::ShutdownAPImain メソッドに移動してやればひとまず解決です。

main.cpp
()

// put_objectメソッド内のInitAPIとShutdownAPI呼び出しをなくす

int main()
{
    Aws::SDKOptions options;
    Aws::InitAPI(options);

    // マルチスレッドで実行
    std::thread th_1(put_object, "hoge3.txt");
    std::thread th_2(put_object, "hoge4.txt");
    th_1.join();
    th_2.join();

    Aws::ShutdownAPI(options);

    return 0;
}

Aws::ShutdownAPI についてはAWS公式のGitHubリポジトリにあるサンプルだと複数回実行しても問題なさそうな実装になっているのですが、シングルスレッドで実行するので問題が発生しないのだと思います。
マルチスレッドで実行する場合はAws::InitAPI と同様にメインスレッドで呼び出すのが無難みたいです。

aws-doc-sdk-examples/s3-demo.cpp at master · awsdocs/aws-doc-sdk-examples
https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/cpp/example_code/s3/s3-demo.cpp

参考

How to handle Aws::ShutdownAPI with multiple threads on Windows? · Issue #1050 · aws/aws-sdk-cpp
https://github.com/aws/aws-sdk-cpp/issues/1050

c++ - Why does an assert(s_monitors) in MonitoringManager::OnRequestSucceeded() fail? - Stack Overflow
https://stackoverflow.com/questions/54290073/why-does-an-asserts-monitors-in-monitoringmanageronrequestsucceeded-fail

aws-doc-sdk-examples/s3-demo.cpp at master · awsdocs/aws-doc-sdk-examples
https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/cpp/example_code/s3/s3-demo.cpp

DockerとMinioでAWS SDK for C++の開発環境を構築する - Qiita
https://qiita.com/kai_kou/items/d160948553504848d380

C/C++によるマルチスレッドプログラミング入門 - Qiita
https://qiita.com/nsnonsugar/items/be8a066c6627ab5b052a

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?