第36講 複数のソフトをナビゲーションソフトから起動する(マルチスレッド研究)☆☆
第5話 新しいスレッドの基に新しいソフトを起動するコード

#pragma endregion
  private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
           Thread^ t=gcnew Thread(gcnew ThreadStart(f1));
           t->Start();
        }
  private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
           Thread^ t=gcnew Thread(gcnew ThreadStart(f2));
           t->Start();
        }
  private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
           Thread^ t=gcnew Thread(gcnew ThreadStart(f3));
           t->Start();
        }
  private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
           Thread^ t=gcnew Thread(gcnew ThreadStart(f4));
           t->Start();
        }
        static void f1(){
           Application::Run(gcnew Form2());
        }
        static void f2(){
           Application::Run(gcnew Form3());
        }
        static void f3(){
           Application::Run(gcnew Form4());
        }
        static void f4(){
           Application::Run(gcnew Form5());
        }
  };
}
このコードの意味は、新しいスレッドを立ち上げ、そのスレッドの上に新しいソフト(Form)を起動せよです。

新しいスレッドの立ち上げ方を説明しましょう。
新しいスレッドを立ち上げるには
Thread^ 変数名=gcnew Thread(gcnew ThreadStart(関数名));
変数名->Start();
です。
これの意味の意味を一つ一つ紐解いてみましょう。
Thread^ 変数名は、新しく立ち上げるスレッドの名前を変数名のところに書いてあるものにします、を意味します。
Thread^はその変数名のデータ型がスレッド型であること意味します。
スレッドに付ける変数名が表す変数は、スレッド型でなければならないと決められているのです。
gcnew Threadが、新しいスレッドを定義します、を意味します。
gcnew ThreadStart(関数名)は、そのスレッド上に関数を展開しなさいです。
(スレッド上に関数を展開するという言い方に、
?を浮かべている初心者もいらっしゃると思います。
ウィキペディアから引用すると『スレッドthread)とは、CPU利用の単位』ですが、
スレッドとはいくつかの処理の束であると思ってください。
そして束を重ねる一つとして関数f1などがあるということです。
スレッドは本で、関数がその中の1ページです。)
そして、変数名->Start();がその名前のスレッドを始めなさいです。
つまり、
Thread^ t=gcnew Thread(gcnew ThreadStart(f1));
t->Start();
なら、
新しいスレッドをtの名前にし、そのスレッドの基に関数f1を展開することにして、スレッドを立ち上げなさい、という意味です。
入門書などでは、
これを
Thread^ threadA=gcnew Thread(gcnew ThreadStart(threadFuncitonA));
threadA->Start();
などと複雑に書くので、初心者は困惑してしまいます。
初心者にとっては、Thread^とthreadAが同じように見え、混乱してしまうのです。
本当は、Thread^ * の*には自分のペットに『ポチ』と名付ける以上の意味はありません。
名前は自由に付けられます。ですから、『タロウ』でもいいわけです。
私の名前『勝一』は一番に勝つだそうですが、そんなものはこじつけで本当は意味などありません。
名前の意味はただ一つです。
他と区別するです。
人間なら他の人と区別するです。
スレッドを複数立ち上げるとき、それぞれに名前を付けておかないとどのスレッドのことを話題にしているかわかりません。
そこで、スレッドを区別するためにThread^ tやThread^ Aなどとして、スレッドにプログラマーが名前を付けているにすぎないのです。
ですから、入門書が推奨している
Thread^ threadA=gcnew Thread(gcnew ThreadStart(threadFuncitonA));
のような書き方は一切必要ないのです。
Aという名前を使いたいなら、私なら
Thread^ A=gcnew Thread(gcnew ThreadStart(fA));
とします。
スレッドの名前をAと定義し、、そのスレッドA上に関数fAを展開しなさい、
とかなりすっきりわかります。
逆に訳した方がわかりやすいでしょうか。
関数fAを展開する新しいスレッドをAという名前にする、です。

ThreadStart(threadFuncitonA))などと書くと、threadは文法で定められていて変更することができないと、
思ってしまいます。
初心者を混乱に陥れる
Thread^ threadA=gcnew Thread(gcnew ThreadStart(threadFuncitonA));
のような書き方は是非ともやめるべきです。

次に
        static void f1(){
           Application::Run(gcnew Form2());
        }
の意味を説明します。
これは、関数f1の内容を記述しています。
関数f1の仕事は、新しいソフトForm2を起動することです。
Application::Run(gcnew Form2());を逆から訳すと、
新しいソフトをForm2の名前にして、そのソフトを起動しなさいです。
この関数は静的関数(static関数)でなければなりません。
つまり、動的関数のように生成消滅を繰り返すのではなく、
常にメモリーに常駐する関数でなければならないのです。
新しいスレッドから起動するする関数は、不安定な動的関数でなく安定的な静的関数でなければならないのです。

第4話へ 第6話へ


戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)