終了処理について

6 posts / 0 new
Last post
n_sugiura
Offline
Last seen: 10 years 7 months ago
Joined: 2013-08-21 16:27
終了処理について

お世話になります。杉浦と申します。

RTC Builderから生成されたコードをみているのですが、 main関数が以下のようになっておりますが、明示的に 終了処理(ライフサイクルの停止やmanagerのdelete等)が 無いのですが良いものでしょうか?

もし必要でしたら正しい終了のさせ方を教えて頂けますでしょうか?

int main (int argc, char** argv) {

  RTC::Manager* manager;
  manager = RTC::Manager::init(argc, argv);

  // Initialize manager
  manager->init(argc, argv);

  // Set module initialization proceduer
  // This procedure will be invoked in activateManager() function.
  manager->setModuleInitProc(MyModuleInit);

  // Activate manager and register to naming service
  manager->activateManager();

  // run the manager in blocking mode
  // runManager(false) is the default.
  manager->runManager();

  // If you want to run the manager in non-blocking mode, do like this
  // manager->runManager(true);

  return 0;
}

Japanese
ysuga
Offline
Last seen: 1 year 7 months ago
Joined: 2011-05-23 10:14
[openrtm-beginners:00479] 終了処理について

杉浦様:
菅です.

まず,RTC Builderで生成されるほにゃららComp.cppに含まれているmain関数は,
おまけのようなもののはずです.

本来,RTC単体はDLLの形で提供されるもので,
RTCの各コールバック関数のみ利用します.
これはRTCを作る側の人に守ってもらいたいことです.

一方で独自のソフトウエアをRTCと通信させるためには,
独自のソフトウエア上でManagerを実体化してRTCを使うことが
必要になると思います.この場合は終了処理を実装する必要がありますよね.

RTCを正しく解放するには,
Managerのshutdownを使います.

RTCを個別に終了するには,
deleteComponent関数を使います.

詳しくはManager.hのコメントを見るか,
Doxygenで生成されたマニュアルを参照してください.

http://www.openrtm.org/OpenRTM-aist/doxygen/ClassReference/classRTC_1_1Manager.html

2013/8/22 :
> お世話になります。杉浦と申します。 RTC
> Builderから生成されたコードをみているのですが、
> main関数が以下のようになっておりますが、明示的に
> 終了処理(ライフサイクルの停止やmanagerのdelete等)が
> 無いのですが良いものでしょうか?
> もし必要でしたら正しい終了のさせ方を教えて頂けますでしょうか?
> int main (int argc, char** argv) { RTC::Manager* manager; manager =
> RTC::Manager::init(argc, argv); // Initialize manager manager->init(argc,
> argv); // Set module initialization proceduer // This procedure will be
> invoked in activateManager() function.
> manager->setModuleInitProc(MyModuleInit); // Activate manager and register
> to
> naming service manager->activateManager(); // run the manager in blocking
> mode // runManager(false) is the default. manager->runManager(); // If you
> want to run the manager in non-blocking mode, do like this //
> manager->runManager(true); return 0; }
>
> _______________________________________________
> openrtm-beginners mailing list
> openrtm-beginners@openrtm.org
> http://www.openrtm.org/mailman/listinfo/openrtm-beginners

Ando Noriaki
Offline
Last seen: 1 year 8 months ago
Joined: 2011-09-04 17:20
[openrtm-beginners:00480] 終了処理について

安藤です

スタンドアロンコンポーネント(*Comp.exe *Comp 等)の正しい終了のしかたは、
1. Ctrl+C (SIGINT) を送る。
2. RTCをRTSystemEditorなどからexitする。
の2通りあります。WindowsでDOS窓の×ボタンを押す、UNIXでkill -9 する
などは、コンポーネントやマネージャの正しい終了処理が呼び出されないため、
ネームサーバにごみが残るなど副作用があるのでお勧めしません。

また、マネージャ自体を停止させる処理をプログラム的に書く場合は
Manager::instance().shutdown();
が正しい停止処理です。

マネージャはrunManager(false) で呼ばれた場合ブロックします。
http://www.openrtm.org/OpenRTM-aist/documents/current/cxx/classreference_ja/classRTC_1_1Manager.html#a9ed639faf15b1a4fbed8969a3df21b71
# ドキュメントにManager::destroy() とあるのはshutdown()の間違いです。

この場合、これはCtrl+C または SIGINT でシグナルハンドラが呼ばれ、
裏で Manager::instance().shutdown(); が呼ばれることによりrunManager() から抜けます。
予め、別にスレッドを立てておいて、そこから Manager::instance().shutdown(); を呼んでも
構いません。

runManager(true) で呼ばれた場合は、ブロックせずにそのまま抜けてきます。
GUIツールキットのイベントループを別途呼び出す必要がある場合は、こちらの
方法でManagerをrunさせます。

この時も、どこか(GUIからとか?)で Manager::instance().shutdown(); を呼ぶことで
マネージャを終了することができます。

あと、もう少し詳しく説明すると、daemonモードでない (コマンドラインオプションに-dをつけたり、
rtc.conf manager.is_master: YESと設定するとdaemonモードになります。) マネージャの場合
コンポーネントが一つも存在しない場合、かつ以下の設定が有効の場合、
manager.shutdown_on_nortcs: YES
manager.shutdown_auto: YES
自動的に Manager::instance().shutdown(); が呼ばれマネージャが終了します。
コンポーネントが存在するかしないかは、manager.auto_shutdown_duration で
設定された周期でチェックしています。

rtc.confで設定可能なオプションについてはこちらをご覧ください。
http://www.openrtm.org/openrtm/ja/content/rtcconf%E8%A8%AD%E5%AE%9A%E9%A0%85%E7%9B%AE%E4%B8%80%E8%A6%A7

2013/8/22 :
> お世話になります。杉浦と申します。 RTC
> Builderから生成されたコードをみているのですが、
> main関数が以下のようになっておりますが、明示的に
> 終了処理(ライフサイクルの停止やmanagerのdelete等)が
> 無いのですが良いものでしょうか?
> もし必要でしたら正しい終了のさせ方を教えて頂けますでしょうか?
> int main (int argc, char** argv) { RTC::Manager* manager; manager =
> RTC::Manager::init(argc, argv); // Initialize manager manager->init(argc,
> argv); // Set module initialization proceduer // This procedure will be
> invoked in activateManager() function.
> manager->setModuleInitProc(MyModuleInit); // Activate manager and register
> to
> naming service manager->activateManager(); // run the manager in blocking
> mode // runManager(false) is the default. manager->runManager(); // If you
> want to run the manager in non-blocking mode, do like this //
> manager->runManager(true); return 0; }
>
> _______________________________________________
> openrtm-beginners mailing list
> openrtm-beginners@openrtm.org
> http://www.openrtm.org/mailman/listinfo/openrtm-beginners
_______________________________________________
openrtm-beginners mailing list
openrtm-beginners@openrtm.org
http://www.openrtm.org/mailman/listinfo/openrtm-beginners

Ando Noriaki
Offline
Last seen: 1 year 8 months ago
Joined: 2011-09-04 17:20
[openrtm-users 02883] [openrtm-beginners:00477] 終了処理について

安藤です

スタンドアロンコンポーネント(*Comp.exe *Comp 等)の正しい終了のしかたは、
1. Ctrl+C (SIGINT) を送る。
2. RTCをRTSystemEditorなどからexitする。
の2通りあります。WindowsでDOS窓の×ボタンを押す、UNIXでkill -9 する
などは、コンポーネントやマネージャの正しい終了処理が呼び出されないため、
ネームサーバにごみが残るなど副作用があるのでお勧めしません。

また、マネージャ自体を停止させる処理をプログラム的に書く場合は
Manager::instance().shutdown();
が正しい停止処理です。

マネージャはrunManager(false) で呼ばれた場合ブロックします。
http://www.openrtm.org/OpenRTM-aist/documents/current/cxx/classreference_ja/classRTC_1_1Manager.html#a9ed639faf15b1a4fbed8969a3df21b71
# ドキュメントにManager::destroy() とあるのはshutdown()の間違いです。

この場合、これはCtrl+C または SIGINT でシグナルハンドラが呼ばれ、
裏で Manager::instance().shutdown(); が呼ばれることによりrunManager() から抜けます。
予め、別にスレッドを立てておいて、そこから Manager::instance().shutdown(); を呼んでも
構いません。

runManager(true) で呼ばれた場合は、ブロックせずにそのまま抜けてきます。
GUIツールキットのイベントループを別途呼び出す必要がある場合は、こちらの
方法でManagerをrunさせます。

この時も、どこか(GUIからとか?)で Manager::instance().shutdown(); を呼ぶことで
マネージャを終了することができます。

あと、もう少し詳しく説明すると、daemonモードでない (コマンドラインオプションに-dをつけたり、
rtc.conf manager.is_master: YESと設定するとdaemonモードになります。) マネージャの場合
コンポーネントが一つも存在しない場合、かつ以下の設定が有効の場合、
manager.shutdown_on_nortcs: YES
manager.shutdown_auto: YES
自動的に Manager::instance().shutdown(); が呼ばれマネージャが終了します。
コンポーネントが存在するかしないかは、manager.auto_shutdown_duration で
設定された周期でチェックしています。

rtc.confで設定可能なオプションについてはこちらをご覧ください。
http://www.openrtm.org/openrtm/ja/content/rtcconf%E8%A8%AD%E5%AE%9A%E9%A0%85%E7%9B%AE%E4%B8%80%E8%A6%A7

2013/8/22 :
> お世話になります。杉浦と申します。 RTC
> Builderから生成されたコードをみているのですが、
> main関数が以下のようになっておりますが、明示的に
> 終了処理(ライフサイクルの停止やmanagerのdelete等)が
> 無いのですが良いものでしょうか?
> もし必要でしたら正しい終了のさせ方を教えて頂けますでしょうか?
> int main (int argc, char** argv) { RTC::Manager* manager; manager =
> RTC::Manager::init(argc, argv); // Initialize manager manager->init(argc,
> argv); // Set module initialization proceduer // This procedure will be
> invoked in activateManager() function.
> manager->setModuleInitProc(MyModuleInit); // Activate manager and register
> to
> naming service manager->activateManager(); // run the manager in blocking
> mode // runManager(false) is the default. manager->runManager(); // If you
> want to run the manager in non-blocking mode, do like this //
> manager->runManager(true); return 0; }
>
> _______________________________________________
> openrtm-beginners mailing list
> openrtm-beginners@openrtm.org
> http://www.openrtm.org/mailman/listinfo/openrtm-beginners
_______________________________________________
openrtm-users mailing list
openrtm-users@openrtm.org
http://www.openrtm.org/mailman/listinfo/openrtm-users

n_sugiura
Offline
Last seen: 10 years 7 months ago
Joined: 2013-08-21 16:27
終了処理について

お世話になります。杉浦です。

何度もすいません。 色々教えて頂きありがとうございます。 色々と試してみましたが、どうしても終了処理がうまく行かず、 行き詰っております。

こちらの前提としまして、以下のようにしています。

・Windows Form(C++/CLR) + DLL(win32) の構成。

・RTM関連の処理は全てDLL内に書く必要がある。

・DLLは動的リンク。

・動的リンクされたとき(DLL_PROCESS_ATTACH)にRTM初期化を行う

・動的リンク解除されたとき(DLL_PROCESS_DETACH)にRTM終了を行う

現在の問題点は、DLL_PROCESS_DETACHのときに、DLLが落ち、 結果的にアプリ全体が落ちてしまう点です。

いくつか試してみたところ、 DLL_PROCESS_DETACHのときに、manager->shutdown()が無いと すぐに落ちます。

DLL_PROCESS_DETACHのときに、manager->shutdown()があると、 ここでブロッキングされて待ち続けてしまいます。

どうしたら正常に終了させることが出来るでしょうか?

終了処理以外は正常に動作できています。

よろしくお願い致します。

Ando Noriaki
Offline
Last seen: 1 year 8 months ago
Joined: 2011-09-04 17:20
[openrtm-beginners:00482] 終了処理について

安藤です

manager->shutdown() 内ではCORBAやManagerのスレッド終了待ちを
している部分があります。そして、DLL_PROCESS_DETACH 時には
スレッド終了待ちをしてはいけないという掟があるようです。
(すると杉浦さんの例のようにデッドロックに陥るようです。)
https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCsQFjAA&url=http%3A%2F%2Fmsdn.microsoft.com%2Fja-jp%2Flibrary%2Fcc429094.aspx&ei=RDgXUrFkh6OTBbrIgZAO&usg=AFQjCNHCn9fmSuN6fAxyKAR_79xq2dOyvg&sig2=3DWgEkjtPmD9W22V6F_htw&bvm=bv.51156542,d.dGI
http://d.hatena.ne.jp/heisseswasser/20120508/1336459226

もしかするとこれが原因かもしれません。

したがって、manager->shutdown() はDllMain内のDLL_PROCESS_DETACH時
ではなく、それ以前に呼んみてはいかがでしょうか?

2013年8月23日 19:03 :
> お世話になります。杉浦です。 何度もすいません。
> 色々教えて頂きありがとうございます。
> 色々と試してみましたが、どうしても終了処理がうまく行かず、
> 行き詰っております。
> こちらの前提としまして、以下のようにしています。
> ・Windows Form(C++/CLR) + DLL(win32) の構成
> ・RTM関連の処理は全てDLL内に書く必要がある。
> ・DLLは動的リンク。
> ・動的リンクされたとき(DLL_PROCESS_ATTACH)にRTM初期化を行う
> ・動的リンク解除されたとき(DLL_PROCESS_DETACH)にRTM終了を行う
> 現在の問題点は、DLL_PROCESS_DETACHのときに、DLLが落ち、
> 結果的にアプリ全体が落ちてしまう点です。
> いくつか試してみたところ、
> DLL_PROCESS_DETACHのときに、manager->shutdown()が無いと
> すぐに落ちます。
> DLL_PROCESS_DETACHのときに、manager->shutdown()があると、
> ここでブロッキングされて待ち続けてしまいます。
> どうしたら正常に終了させることが出来るでしょうか?
> 終了処理以外は正常に動作できています。
> よろしくお願い致します。
>
>
_______________________________________________
openrtm-beginners mailing list
openrtm-beginners@openrtm.org
http://www.openrtm.org/mailman/listinfo/openrtm-beginners

Log in or register to post comments

Download

latest Releases : 2.0.0-RELESE

2.0.0-RELESE Download page

Number of Projects

Choreonoid

Motion editor/Dynamics simulator

OpenHRP3

Dynamics simulator

OpenRTP

Integrated Development Platform

AIST RTC collection

RT-Components collection by AIST

TORK

Tokyo Opensource Robotics Association

DAQ-Middleware

Middleware for DAQ (Data Aquisition) by KEK