「なでしこv1」開発掲示板

なでしこv1のバグや要望を書き込む掲示板
[一覧へ] > (@733) [低] [アイデア]
@733■ (#2317) マルチスレッドが手軽に使えるように - AI (2014-08-13 17:21) /低 アイデア
【要望】
現在、しらたまさんの関数ポインタ等を使えばマルチスレッドに出来るようですが
複雑で関数をEVALするなどしないと出来ないようです。
もっと手軽に出来るようになれば活用の幅も広がると思います。

用途例
コールバック処理。
大量のデータを使うループ処理
ゲームプログラミング等のバックグラウンド処理
など、劇的にやりやすくなると思います。

//ここから
データベース処理中フラグとは整数=オフ。
バックグラウンド処理とはスレッド。
バックグランド処理の関数=`データベース登録`。
バックグランド処理の関数引数=「`テーブル名`,"{データ}"」。
バックグランド処理の開始。

バックグランドの処理完了した時は~
 バックグランド処理の停止。
 データベース処理中フラグ=オフ。
 `データベースの登録が完了しました`と言う。

●データベース登録(テーブル名,データ)~以下SQL文など省略
//ここまで

(#2319) Re: マルチスレッドが手軽に使えるように - うぇいく (2014-08-13 20:12) /低 アイデア
 内部構造的にマルチスレッドに対応していないため、簡単なサンプルではうまく動くように見えても、実際に処理を書いたら動かないと思いますよ(メインスレッド以外のスレッドからは、なでしこの変数やユーザ定義関数や命令を一切使わないのなら、大丈夫 かも)
メインスレッドが何もしていない状態ならば、その間に他のスレッドが起動されて終了するということはできると思いますが、これならばユーザ関数の呼び出しと変わりません。
 Plugin含めてすべて作り直せば対応できないことはないと思いますが、おそらく、「1から作り直した別物」になると思いますので、だれかが、「マルチスレッド版なでしこ」として、新たに作るのではない限り難しいのではと思います。
(そして、おそらく、マルチスレッドを考慮した実装にすると、シングルスレッドでの動作は遅くなります)
と、私は考えています。

もしくは、よい実装ほうほうがあれば、取り込まれるかもしれません。
基本的に、スレッド間で共有されるリソースが多いほど調整が大変になるので、完全に独立させてしまうのが1番単純にはなります。

(#2320) 勘違いしてました - AI (2014-08-14 16:11) /低 アイデア
うぇいくさん説明頂きありがとうございます。
勉強不足でお手数かけます。

>完全に独立させてしまう
独立して動くイメージしていたのですが、
マルチスレッド→別プロセスで動くものと勘違いしてました。
(別プロセスで動く関数のことだと勝手に思っていました)
スレッドはあくまでプロセス内での処理単位のことなんですね。

前提が間違ってて、そのうえ、思ったより大変そうだと解り
現実的でなければ、この要望は取り下げるべきかと思ていますが

別プロセス上で非同期で動く関数であっても困難でしょうか。



(#2321) Re: マルチスレッドが手軽に使えるように - うぇいく (2014-08-14 16:35) /低 アイデア
ここで書いた「完全に独立させてしまう」というのは、プロセスは1つで考えています。
ただし、実行環境(変数やソース上のどの部分を実行しているか 等)は、各スレッドで別々に管理して、相互には更新も参照もできない状態です。
この場合でも、「GUIへのアクセスはメインスレッドのみ」という制約はかかる(Windowsの制限)のと、機能によっては呼び出し元がメインスレッドを前提としていて使えないものもあるので、別プロセスのほうが単純でわかりやすいため、使い勝手は別プロセスのほうが良いかもしれません。

なお、スクリプト言語にも、もともとシングルスレッドから、疑似マルチスレッドを経て完全マルチスレッドに進化した言語もあります(Rubyです。大改修だったようですが)

(#2322) 返信ありがとうございます。 - AI (2014-08-15 19:21) /低 アイデア
度々恐れ入ります。
なるほど、「完全に独立させてしまう」そう言うことだったんですね。
解ってませんでした。

返信いただいてから、考えてみたんですが、
僕の、知識的に言語の内部を理解できるレベルではないので、出来る範囲で、
イメージしていたものに近い動作のものを作成してみました。

(別途、実行ファイルを使うので、当初要望の別プロセスで動く関数と言う定義の枠を超えた仕様にしてしまいましたが)

問題は、
処理スピードが出ないので、ゲームなどの当り判定などのリアルタイムのバックグラウンド処理に向かない。
exeファイルを別途配布する必要がある。(必要なプラグインも)

なので、使われるシーンは、余程の大きなデータを読み書きしたり。
複数のダウンロードを同時に行うなどの用途に絞られてしまいますが。

処理が遅い要因は、
必要ファイルの作成とCOPYDATA送受信の部分にあると思います。
exeの実行のトリガーの起動命令も処理が重い部分では無いかと思います。

別件で出している要望の共有メモリ@734の件でも出していますが
メモリの共有など工夫すれば、もっとシンプルに高速できるかもしれませんが今のところ先は見えてません。


//MultiTask\実行エンジン.exe//←のディレクトリと名前で直ぐ下のコードの実行ファイルを作成して保存。
//プラグインフォルダも同じ階層に配置します。
!母艦設計=`母艦の可視=オフ`。
!`プロセス.nako`を取込む。
終わる。
//ここまで


ここから下のコードで上のexeに渡す、コードを`プロセス.nako`ファイルとして作成して実行したり結果を処理してます。


//処理側側コード//MultiTaskフォルダと同じ階層に適当な名前で保存して実行
別プロセス結果とは文字列
母艦のCOPYDATA受けた時は~母艦のCD_ID&`,`&母艦のCD文字列&改行を別プロセス結果に追加。

10回
 別プロセス[回数]をプロセスとして作成。
 別プロセス[回数]→コード="{母艦のハンドル}に({時間の掛かる処理})を({回数})でCOPYDATA詳細送信"。
 別プロセス[回数]→実行。
母艦=`通常100秒以上掛かる処理も10秒程度で処理できます。`

別プロセス結果を表示。

●時間の掛かる処理~"_=10秒待って、100の乱数&`,`&{CPU使用率取得}。"で戻る。


■プロセス
 ・コード ←コード設定 →コード取得
 ・ソースファイル ←ソースファイル設定 →ソースファイル取得
 ・実行結果
 
 ・実行~実行エンジンを起動して後始末。
 ・同期実行~実行エンジンを起動待機して後始末。

 ・コード取得~_=実行プロセスを開く。  
 ・コード設定({文字列}S)~
  実行プロセスが存在でなければ、Sを実行プロセスに保存。 
  違えば、重複実行エラー処理する。
  
 ・ソースファイル取得~_=ソースファイル_。  
 ・ソースファイル設定({文字列}S)~
  実行プロセスが存在でなければ、
   Sが存在ならば、Sを開いて実行プロセスに保存。
   違えば、`ソースファイルが見つかりません。`でエラー発生。
  違えば、重複実行エラー処理する。

 ・後始末~実行プロセスをファイル完全削除。

 ・重複実行エラー処理~`別のインスタンスの実行プロセスの実行を先に済ませて処理してください`でエラー発生。
  
 ・作る~
  実行パス=母艦パス&`MultiTask\`。
  実行プロセス=実行パス&`プロセス.nako`。
  実行エンジン=実行パス&`実行エンジン.exe`。
  (プロセスのインスタンス作成済)でなければ、実行プロセスが存在ならば、実行プロセスをファイル完全削除。
  プロセスのインスタンス作成済=はい。

 ・使い方~"別プロセスで実行するコードを設定するか実行ファイルを設定し実行メソッドを呼出します。"と言う。
  
 ・{非公開}実行エンジン
 ・{非公開}実行プロセス
 ・{非公開}ソースファイル_
 ・{非公開}インスタンス作成済{=0}

//ここまで

(#2317)へ返信する:

👆お手数ですが、いたずら防止のために、「真夏」の読み方を記入してください。

編集時に使うキーを入力(省略可能)

画像ファイル(最大300KB)を添付可能