ライブラリ: マルチテスター - ページ 30

 
Stanislav Korotky #:

ソースの変更点には、クリップボードで何かが行われたとは書かれていなかった。

  static bool GetSettings2( string &Str, const int Attempts = 10 )
  {
    bool Res = false;

    if (MTTESTER::LockWaiting())
    {
      Res = MTTESTER::GetSettings(Str, Attempts);

      MTTESTER::Lock(false);
    }

    return(Res);
  }

最適化を実行すると、使用可能なすべてのコアが一度に使用されるのではないですか?1つのテストが最適化から1つのコアを "奪った "ことが理解できない(実際、最適化MTの2エージェントでさえ無効とマークされている)。

すぐに書いたと 思います。最適化ターミナルには無効化されたエージェントが2つある。有効なエージェントはそれぞれ1コアを取る。

 
fxsaber #:

すぐに書いたと 思う。Optimising Terminalには2つの無効なエージェントがある。有効なエージェントはそれぞれカーネルを取る。

手動での 無効化(あるいはエージェントのその他の設定)については何も明示的に書かれていない - そしてこのニュアンスはまだ迂回されている。これが、並列作業がどの程度自動化されているのかについて私が疑問を持った理由です。私はトピックやブログの説明から、完全自動化が行われていると素朴に考えていた。

LockWaitingは見たことがある。私がファイル作業をロックするものとして定式化したものだ。ロックがクリップボードを含むリソースへのアクセスに使えることは明らかだ。用語の混乱。

追記。私が何かを誤解しているのかもしれないが、クリップボードへの排他的なアクセスだけが必要なのであれば、同じロック(定期的なチェックを伴うループ)をクリップボード自体の機能(ソースコードですでに言及されているOpenClipboard)に対して行う方が論理的である。

 
Stanislav Korotky #:

手動で エージェントを無効にする(あるいはその他の方法でエージェントを設定する)ことについては何も書かれていない。これが、並行作業がどの程度自動化されているのかについて私が疑問を持っている理由だ。私は、トピックやブログの説明から、完全な自動化が行われていると素朴に考えていた。

MQ側での完全自動化。どのマシンでも、たとえ1つのターミナルで作業していても、私は1-2エージェントのスイッチを切る。


Terminal1 (最適化):エージェント 3000-3017 - 有効、30018-3019 - 無効。他の端末は最初の端末の完全なコピーなので、すべての端末でそうします。手動設定は行わない。

ターミナル2 - シングルパス用。


2つのシナリオがある。

  1. まずターミナル1で最適化を実行し、3000-3017をオンにした。次にTerminal2でシングルパスを行い、3018が機能した。
  2. 最初にTerminal2でシングルを実行し、3000がオンになった。その後、Terminal1で最適化を実行 - 3001-3018を実行。
すべてはMQ側で自動化されている。確認は1分もあればできる。ダイアログはもっと時間がかかった。
 
Stanislav Korotky #:

追記おそらく私は何かを誤解しているのだろうが、クリップボードへの例外的なアクセスだけが必要なのであれば、クリップボード自体の機能(ソースですでに言及されているOpenClipboard)で同じロック(定期的なチェックを伴うループ)を行う方が論理的だろう。

そのような解決策に論理性があるとは思えません。

 
fxsaber #:

MQ側の完全自動化。どのマシンでも、たとえ1台の端末で作業していても、1-2台のエージェントのスイッチを切ることで、タイムラグなく作業することができます。


Terminal1 (最適化):エージェント 3000-3017 - 有効、30018-3019 - 無効。他の端末は最初の端末の完全なコピーなので、すべての端末でそうします。手動設定は行われない。

ターミナル2 - シングルパス用。


2つのシナリオ。

  1. まずターミナル1で最適化を実行し、3000-3017がオンになっている。次にTerminal2でシングルを実行したところ、3018が実行されている。
  2. 最初にTerminal2でシングルを実行し、3000が動作している。次にTerminal1で最適化を実行したところ、3001-3018が動作した。
すべてMQ側で自動化されている。確認は1分もあればできる。ダイアログはもっと時間がかかった。

もしこの説明がブログにあれば、疑問はなかっただろう。繰り返すが、この記述はエージェントの手動設定を意味するものであり、自動化を意味するものではない。確認することは何もない。

 
Stanislav Korotky #:

もしこの説明がブログにあれば、疑問はなかっただろう。繰り返しますが、この記述はエージェントの手動設定を意味します。確認することは何もない。

手動設定はありません。エージェントに何もしなくても、動作は変わりません。驚くべきことです。

 
fxsaber #:

手動設定はない。エージェントに何もできなくても、動作は変わりません。驚くべきことだ。

"並列テスターで作業する際に起こりうるコンフリクトを避けるため "と記載されています。実際に行われているのはエージェントの手動設定ですから。なぜかあなたは、ポートの割り当てをコアと関連付けることに固執しています。ポートはオーバーラップできませんが、カーネル(プロセス)はオーバーラップできます。私たちは、並列プロセス間の自動的な競合解決について、異なる概念を持っているだけなのでしょう。

 
Stanislav Korotky #:

これは、"並列テスターで作業する際に起こりうるコンフリクトを回避するため "である。この表現はカーネルの文脈では誤解を招きかねない。なぜなら、実際にはエージェントの手動設定が行われるからである。

あなたは "circumvention" という単語を誤解しています。この問題は、複数の端末が同時にクリップボードを操作している場合に発生します。以前は、ある端末からのジョブが誤って別の端末に入ってしまうことがありました。今は除外されています。

 

以下の変更がMTTester.mqh で利用可能です。

  • GetLastTstCacheFileName は、パスなしで tst ファイルの名前を返すようになりました。
  • GetLastTstCache には、直前に完了したパスに対応する tst ファイルをフェッチする機能があります。これにより、誤った tst ファイルがフェッチされることがなくなりました。
  • ClickStart は、スタートボタンが押された時にテスターが即座に反応する場合でも正しく機能します。このような場合、ClickStartはStartボタンが正常に押されたことを認識します。
 

時には、作業中の端末で同じことをする必要がある。この動作の自動化を以下に例として示す。


同様のスクリプトRunMe.mq5を 実行して、各端末のデータを収集する必要がある。

#include <fxsaber\MultiTester\MTTester.mqh> //https://www.mql5.com/ja/code/26132
  
void OnStart()
{
  if (MTTESTER::LockWaiting()) // アクションを連続して実行したい場合。
  {
    const int handle = ::FileOpen(__FILE__, FILE_WRITE | FILE_READ | FILE_ANSI | FILE_COMMON);

    // 必要なデータをファイルに書き込む。
    if (handle != INVALID_HANDLE)      
    {
      FileSeek(handle, 0, SEEK_END);
      FileWriteString(handle, "Account = " + (string)AccountInfoInteger(ACCOUNT_LOGIN) + ", " +
                              "Balance = " + (string)AccountInfoDouble(ACCOUNT_BALANCE) + "\n");
      
      FileClose(handle);
    }

    MTTESTER::Lock(false); // 並列実行ロックを解除する。
  }
}


これがその方法である。

// すべての端末でスクリプトを実行する。

#include <fxsaber\MultiTester\MTTester.mqh> //https://www.mql5.com/ja/code/26132
  
void OnStart()
{
  HANDLE Handles[]; 
  
  // すべての端末に目を通す
  for (int i = MTTESTER::GetTerminalHandles(Handles) - 1; i >= 0; i--)
    MTTESTER::RunEX5("Scripts\\RunMe.ex5", Handles[i], true); // そしてそれぞれに適切なスクリプトを実行する。
}


その結果、ワンクリックですべての端末からデータを収集することができた。MTTESTER::RunEX5- 必要な端末(ポータブル)でEX5を実行する - のおかげです。