サブスレッドからメインスレッドの手続き呼び出しについて


熊蔵  2016-04-02 07:04:13  No: 48138

初めまして、さんざん調べまくりましたが、よく解らず投稿致しました
宜しくお願い致します。
やりたいこと
・測定器のデータをシリアルで受信しロギングファイルを作成する
  1データ約40バイトくらいのテキストデータ
・同時にDI/Oの入力を監視し(8点)、各入力ごとに上記ロギングファイルにデー  タを追記する
・シリアル受信とDI/O入力は代わる代わる発生する

以上を実現するために以下のような構成のプログラムを作成しました
==メインスレッド==
グローバル変数:A(string=ロギングデータ)

<シリアル受信処理>
・シリアルデータの受信、データ整形
・ロギングデータ生成関数呼び出し

<ロギングデータ生成>
・ロギングデータをAに代入
・ファイルセーブ関数を呼び出し

<ファイルセーブ>
・追記モードでテキストファイルを開き、Aの内容をwritelnで書き込み保存

==サブスレッド==  //シリアル通信と平行して(全く同時に処理することはな    い)
・DI/Oの入力が入るごとに、Aにデータを代入し
・メインのロギングデータ生成関数呼び出し
・メインのファイルセーブ関数呼び出し
※何れもSynchronizeメソッドを使って、呼び出しています

以上で出来たロギングファイルを、上記プログラム実行中「VNC」を使って他のPCから覗いています

質問です
1,サブスレッドからメインの関数を呼び出すのは、やっても良いことなのか
2,時々受信データが、あるべき位置に書き込まれていなかったり、逆にDI/
  Oのデータがやはりあるべき位置に書き込まれていないという不具合が起きま  す。その原因がサブスレッドからメインスレッドの関数を呼び出すことにあ  るのでは、と何の根拠も無いのですが。
3,サブスレッドからメインスレッドの関数呼び出しがNGだと思った理由は、    色々調べたのですが、そのような例が一つも見当たらなかったからです。

以上、どなたかどうぞご教示宜しくお願い致します。


Nov  2016-04-02 09:54:34  No: 48139

アョ良いと思います。ただしクラスメソッドの場合はフィールドアクセス
  には注意が必要ですけど。
イョチにアクセスするすべてのメソッドにクリティカルセクションが設定
  されていれば、前後はしても抜けることはないと思います。
  デッドロックが怖いですけど。
ウョこれは質問でしょうか。
スススススススススススススススススススススススススススススススススススススススス
ニコ 熊蔵
トコ イーアカッーエッーウィ日ゥ アーコークコイウ シ  スュアセシ初心者セ シッニセシノヘヌ ス「コッッョョョッッアョ「 ス「ー「セ 書込者ノト:ロ 「「、。「 ン

ホ様
早速に有難うございました。まずお礼申し上げます。
アャサブスレッドからも関数呼び出しOKということで、ホッと致しました。
イ,クリティカルセクションの設定ですが、使ったことが有りません。
  検索してみましたが、メチトヲサモヤユトノマのネにあることと、ネット上にある例
  では、若干違っていてどうしたら良いのか今のところ判りません。
  トのバージョンによって違うような。
  モメソッドを使って呼び出せば、バッティングは起きないものと
  思っていました。もう少し調べ考えてみます。どうしてもわからない時はま
  た質問させて頂きます。その節は宜しくお願い致します。
ウャ質問では有りません。サブスレッドからメインの関数を呼び出す例文を探し  きれなかったので、そういう使い方はしないものなのかなと思った次第です

※肝心なことを忘れていました。
  ・開発環境:トイーーキ  ラキ゜カエ
  ・実行環境  ラキヲサウイ

お礼が遅くなって、申し訳有りませんでした。また宜しくお願い致します。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアカッーエッーウィ日ゥ イーコウエコアイ  書込者ノト:ロ 」。ィ、 ン

分かる範囲内ですが、
アョモはメインスレッドと同期しますので、
多用するとそもそも別スレッドを作成する意味がなくなります。
モ内でモ使うと固まりますよね?
それ以外の場所でモ使っても固まりませんよね?
そういうことです。
普通、シリアル通信を別スレッドで行います。
でないと、ウィンドウを動かしただけで通信が止まっちゃいますよ。
イョ通信の不具合は問題を顕著にするためにモでラグを入れて、
それで同様の不具合が起こるならデータアクセス頻度の問題かと思います。
ウョホヌではないです、プログレスバーなんかはまさにそういう使い方が多いです。
スススススススススススススススススススススススススススススススススススススススス
ニコ 熊蔵
トコ イーアカッーエッーエィ月ゥ イアコエイコオク シ  スュアセシ初心者セ シッニセシノヘヌ ス「コッッョョョッッアョ「 ス「ー「セ 書込者ノト:ロ 「「、。「 ン

ヲサ様

ご指摘有難うございました。

モを使った理由は、メインの他の関数が呼び出す頻度が高い関数を
サブスレッドから呼び出すので、使用しました。
調べてみたのですが、どうもよく解らないので質問させていただきます。
・モとクリティカルセクションの違いです
  モは制御をメインに移すが、使用中の変数をロックはしないが
  クリティカルセクションはロックする、ということでしょうか?
  ではモとクリティカルセクションを同じルーティンで同時に使
  う事は有りなのでしょうか?

・クリティカルセクションで保護するグローバル変数は、当然メインの中で
  至る所で使用されることがあるかと思います。その場合、サブスレッドだけ  でなく、メインでもその変数にアクセスする場合、クリティカルセクション  で囲まなければならないのでしょうか。ヘルプには「クリティカルセクショ  ンが機能するのは,すべてのスレッドが・・・」と有ります。
  メインの至る所に、クリティカルセクションが置かれるということ??

・クリティカルセクションの使い方でヘルプには「チ」と「メ」で  囲って有ります。しかし、「ナ」と「フ」で囲ってある例もネット上  には有ります。どのような違いがあるのでしょうか。

・具体的なコードを示さず、一般論ばかりで申し訳ありませんが、基本的な考  え方を理解しないと、誤った方向に行ってしまいそうで、どうぞ宜しくお願  い致します。

※シリアル通信はサブスレッドで処理するもの、というご指摘について。
  通信処理には「ホメテマヘヘ」というコンポーネントを使っています。ご存知かと
  思いますが、昔のヘモテマヘヘみたいなもので、手軽に実装できるので常用してい  ます。フォームに貼り付けて使うので、今まで別スレッドに実装するなど考  えたことも有りませんでした。今回スレッドを使うにあたって、シリアル通  信は、サブスレッドで実装した方が良いのかな・・と考えたりしたのですが
  メインに貼り付けたホメテマヘヘをサブスレッドから操作するのは、如何なものか
  と、易きに流されてしまいました。

以上、長くなりましたが、どうぞ宜しくお願い致します。
スススススススススススススススススススススススススススススススススススススススス
ニコ ホ
トコ イーアカッーエッーオィ火ゥ ーーコオアコーイ  書込者ノト:ロ 」、ヤァ」、マヘノテナトタタシソク
ウ ン

モもメインスレッドを待機するので、結果的にロックしていること
になるかと思います。メソッド経由でも同じことです。
つまり、ロギングデータ生成部を他のスレッドが使用している間は待機してい
るため、その間の処理が止まっている恐れがあります。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアカッーエッーオィ火ゥ ーアコウカコオケ  書込者ノト:ロ 「「・ ン

まず、モもヤテモもコードの同時アクセスを防ぐものです。
違いが判らなければ同じものと解釈して良いです。
とだって同じに見える人には同じですし、違いが分かる人は使い分けをします。
その程度の違いです。

ヲサヲサ・クリティカルセクションで保護するグローバル変数は、当然メインの中で
ヲサヲサヲサ  至る所で使用されることがあるかと思います。
書き込み専用のメソッドを用意するとか、適当にクラスを作成すればさほど困難な作業ではないかと思います。

ヲサヲサ・クリティカルセクションの使い方でヘルプにはョョョ
コッッョョッフッモッッモョモマョヤテモ
コッッョョッフッモッッモョテョヤヤョモ
関連項目もチェック!

ヲサヲサ※シリアル通信はサブスレッドで処理するものョョョ
コッッョョッッイウイョ
コンポーネントをお使いならスレッドとか気にしなくてよいです。
私が書いたことは聞き流してください。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアカッーエッーオィ火ゥ ーケコアーコエア シ  スュアセシ中級者セ シッニセシノヘヌ ス「コッッョョョッッイョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン

スレッドは基本的に時間がかかる処理を別プロセス等に任せて
メインの処理に負担をかからずにするためのものです。

公式より「マルチスレッドアプリケーション」
コッッョョッッッウオケカア

シリアル通信はお使いのコンポーネント内でスレッドを使った
通信が行われていると思いますのでスレッドは使わなくて大丈夫です。
スレッドからコンポーネント呼ぶのはエラーの元ですし

もう1つの要素トノッマの入力がものすごく頻繁に見ないといけないとすると
それはスレッドを使った方が良いと思われます。

じゃあトノッマをスレッドで監視してロギングファイルを作成するには?
と問われるとなかなか良いサンプルがありません。

1.スレッド内でロギングファイルを作成する
  あまりお薦めはできません。
2.スレッド内で監視してメインスレッドの関数を呼ぶ
  ヨテフが絡まなければモを使う必要は無いけどこれもどうかと
3.モヘ/ミヘヲサを使用する
  この方法を薦めたいのですが世の中にサンプルが少ない

やっと見つけました
コッッョョッペチ゜ヤッ

この方法を使うと
スレッド側から呼び出す処理に時間がかからずすぐに次の処理に戻ることが出来るのと
メインスレッド側はヨテフを操作して良いタイミングでメッセージを受け取ることが出来る
という特徴があります。

メッセージ応答型のアプリケーションは
非同期チミノを扱うときにも役に立ちますので
最初は難しいですが覚えておいた方が良いと思います。
スススススススススススススススススススススススススススススススススススススススス
ニコ 熊蔵
トコ イーアカッーエッアウィ水ゥ イイコイイコオク シ  スュアセシ初心者セ シッニセシノヘヌ ス「コッッョョョッッアョ「 ス「ー「セ 書込者ノト:ロ 「「、。「 ン

ホ様、様、様

皆様ご教示有難うございました。
エッオから深夜残業が続き、そのまま出張が入ってエッアイに帰宅。
疲労困憊で、未だ十分内容を読み込めておりません。
しっかり読み込んで、改めてご報告致しますので、しばらく
時間を下さい。
取り急ぎお礼まで。
スススススススススススススススススススススススススススススススススススススススス
ニコ ホ
トコ イーアカッーエッアエィ木ゥ ーーコアイコイア  書込者ノト:ロ 」、ヤァ」、マヘノニソスシサ  ウ ン

お疲れ様です。

モは自分がブロックされるので、ムを使うという手もあります。
単にモをムに置き換えるだけ(使ったことはありませんが)
なので簡単ですが、シーケンシャルな処理が必要な場合は、向いてませんね。
スススススススススススススススススススススススススススススススススススススススス
ニコ ホ
トコ イーアカッーエッアエィ木ゥ ーーコアオコエウ  書込者ノト:ロ 」、ヤァ」、マヘノニソスシサ  ウ ン

注)↑待機しなくなるので、適度にモを入れないと、テミユ負荷がうなぎ
    のぼりになりそうです。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアカッーエッアエィ木ゥ アーコアエコーア  書込者ノト:ロ 「・「   ン

参考までにですが・・・
私も仕事で同じようなことをちょうどやってまして、
スレッドを分ける代わりに、2つのアプリを作成し、
お互いはアトムで通信してデータ作成などやってます。

こうすると、当然ですが両方ともメインスレッドで動作しますし、
作成も単純になりますし、安定した動作にもなってますよ。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加