avatar of 发明者量化-小小梦 发明者量化-小小梦
フォロー ダイレクトメッセージ
4
フォロー
1271
フォロワー

ポリシー プログラムを実際に同時に実行できるようにし、JavaScript ポリシーにシステム レベルのマルチスレッド サポートを追加します。

作成日:: 2023-03-02 14:19:15, 更新日:: 2024-03-20 15:06:41
comments   3
hits   2081

ポリシー プログラムを実際に同時に実行できるようにし、JavaScript ポリシーにシステム レベルのマルチスレッド サポートを追加します。

ポリシー プログラムを実際に同時に実行できるようにし、JavaScript ポリシーにシステム レベルのマルチスレッド サポートを追加します。

JavaScript 言語を使用して FMZ で戦略を開発する場合、戦略アーキテクチャはポーリングです。同時設計シナリオがある場合、それはexchange.Go関数は、いくつかのインターフェースへの同時呼び出しを行うために使用され、それによっていくつかの同時シナリオのニーズを満たします。しかし、一連の操作を実行するために別のスレッドを作成したい場合は、それは不可能です。たとえば、Pythonのように、threadingこのライブラリは並行設計を行うために使用されます。

この需要に基づいて、FMZ プラットフォームは基盤システムをアップグレードしました。真のマルチスレッド サポートも JavaScript 言語に追加されました。詳細な機能は次のとおりです:

  • カスタム関数を同時に実行するためのスレッドを作成します。
  • スレッド間通信。
  • スレッド間で保存された変数を共有します。
  • スレッドの実行が完了するまで待機し、リソースを再利用して実行結果を返します。
  • スレッドを強制的に終了し、リソースを再利用します。
  • 同時スレッド実行関数で現在のスレッド ID を取得します。

次に、エディターが各機能を 1 つずつ理解できるように案内します。

カスタム関数を同時に実行するためのスレッドを作成する

__Thread関数はスレッドを作成して関数を同時に実行できます。たとえば、並行関数を作成する必要がありますfunc1func1この関数は何をしますか? 0から9まで累積させることができます。この段階的な累積プロセスを確認するには、func1関数でforループを使用して、一定期間ごとに一時停止します(Sleep関数は、特定のミリ秒数の間スリープするために使用されます)。時間の。

function func1(sleepMilliseconds) {
    var sum = 0 
    for (var i = 0 ; i < 10 ; i++) {
        sum += i 
        Sleep(sleepMilliseconds)
        Log("sum:", sum)
    }
    
    return sum
}

function main() {
    // 使用__Thread函数并发创建一个线程,参数200即为func1函数的参数,
    // 如果func1函数有多个参数,这里就具体传对应的参数
    var thread1Id = __Thread(func1, 200)
    
    // 这里需要等待线程Id为thread1Id的线程执行结果,否则main函数执行完就直接释放所有线程
    var ret = __threadJoin(thread1Id)
    Log("ret:", ret)
}

実際のアプリケーション シナリオでは、次のように同時 HTTP リクエストを行うことができます。

function main() {
    let threads = [
        "https://www.baidu.com",
        "https://www.163.com"
    ].map(function(url) {
        return __Thread(function(url) {
            Log("GET", url)
            return HttpQuery(url)
        }, url)
    })
    threads.forEach(function(tid) {
        Log(__threadJoin(tid))
    })
}

スレッドの実行が完了するまで待機し、リソースを再利用して実行結果を返します。

上記の例では、最終的にメイン関数で使用しました。__threadJoin同時実行スレッドの実行が完了するまで待機する関数、変数ret引き継ぐ__threadJoin関数の戻り値。この戻り値を出力し、この同時スレッドの実行の特定の結果を確認します。

// id:线程ID,terminated:是否被强制停止,elapsed:耗时(纳秒),ret:线程执行函数的返回值
ret: {"id":1,"terminated":false,"elapsed":2004884301,"ret":45}

スレッドを強制的に終了し、リソースをリサイクルする

function func1(sleepMilliseconds) {
    var sum = 0 
    for (var i = 0 ; i < 10 ; i++) {
        sum += i 
        Sleep(sleepMilliseconds)
        Log("sum:", sum)
    }
    
    return sum
}

function main() {
    var thread1Id = __Thread(func1, 200)
    Sleep(1000)
    retThreadTerminate = __threadTerminate(thread1Id)
    Log(retThreadTerminate)   // true
}

前の例をもう一度取り上げると、スレッドを作成した後、1 秒待ってからスレッドの実行を強制的に終了することができます。

スレッド間通信

スレッド間通信が主に使用される__threadPostMessage機能と__threadPeekMessage関数。次の簡単な例を見てみましょう。

function func1() {
    var id = __threadId()
    while (true) {
        var postMsg = "来自id:" + id + "的线程函数func1的消息"
        __threadPostMessage(0, postMsg)              // 发送消息到主线程
        var peekMsg = __threadPeekMessage()         // 接收来自其它线程的消息
        Log(peekMsg)
        Sleep(5000)
    }
}

function main() {
    var threadId = __Thread(func1)
    
    while (true) {
        var postMsg = "来自主线程的main函数的消息"
        __threadPostMessage(threadId, postMsg)
        var peekMsg = __threadPeekMessage()
        Log(peekMsg, "#FF0000")                     // #FF0000 , 设置日志为红色用于区分
        Sleep(5000)
    }
}

__threadPostMessageこの関数はスレッドにメッセージを送信するために使用されます。最初のパラメータは、メッセージが送信される特定のスレッドのIDであり、2番目のパラメータは送信するメッセージです。これは文字列、数値、配列、JSON オブジェクトなど。並行スレッド関数では、メイン スレッドにメッセージを送信できます。メイン スレッドの ID は 0 として定義されます。

__threadPeekMessageこの関数は、スレッドによって送信されたメッセージを監視するために使用されます。タイムアウト (ミリ秒単位) を設定するか、0 に設定してスレッドをブロックし、メッセージが返されるまで監視することができます。

もちろん、メインスレッドと通信する同時スレッドは除きます。同時実行スレッドは相互に直接通信することもできます。

同時スレッド実行関数で現在のスレッドIDを取得する

上記の例では、var id = __threadId()__threadId()この関数は現在のスレッドの ID を取得できます。

スレッド間で保存された変数の共有

スレッド間の通信に加えて、相互作用のために共有変数を使用することもできます。

function testFunc() {
    __threadSetData(0, "testFunc", 100)   // 储存在当前线程环境,键值对 testFunc : 100 
    Log("testFunc执行完毕")
}

function main() {
    // threadId为1 ,创建的threadId为1的线程会先执行完,只要线程资源没有被回收,线程本地储存的变量就有效
    var testThread = __Thread(testFunc)
    
    Sleep(1000)

    // 输出 in main, get testFunc: 100
    Log("in main, get testFunc:", __threadGetData(testThread, "testFunc"))   // 取出键名为testFunc的值
}

上記はすべての機能の簡単なデモンストレーションです。