﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/css' href='https://stocksharp.ru/css/style.css'?>
<?xml-stylesheet type='text/css' href='https://stocksharp.ru/css/bbeditor.css'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">Concurrent Strategy Execution with JavaScript Multithreading Support</title>
  <id>~/topic/25697/concurrent-strategy-execution-with-javascript-multithreading-support/</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-04-12T01:39:41Z</updated>
  <logo>https://stocksharp.ru/images/logo.png</logo>
  <link href="https://stocksharp.ru/handlers/atom.ashx?category=topic&amp;id=25697" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.ru/posts/m/80291/</id>
    <title type="text">When developing strategies on FMZ using the JavaScript language, since the strategy architecture is ...</title>
    <published>2024-04-17T01:07:43Z</published>
    <updated>2024-04-17T01:07:43Z</updated>
    <author>
      <name>Trading</name>
      <uri>https://stocksharp.ru/users/186421/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">When developing strategies on FMZ using the JavaScript language, since the strategy architecture is polled. If there is a concurrent design scenario, the ```exchange.Go``` function is used to make concurrent calls to some interfaces, so as to meet the requirements of some concurrent scenarios. But if you want to create a single thread to perform a series of operations, it is impossible. For example, like the Python language, use the ```threading``` library to do some concurrent design.&lt;br /&gt;&lt;br /&gt;Based on this requirement, the FMZ platform has upgraded the bottom layer of the system. True multithreading support has also been added to the JavaScript language. Detailed features include:&lt;br /&gt;&lt;br /&gt;- Create threads to execute custom functions concurrently.&lt;br /&gt;- Inter-thread communication.&lt;br /&gt;- Variables stored between shared threads.&lt;br /&gt;- Wait for the thread to finish executing to reclaim resources and return the execution result.&lt;br /&gt;- Forcibly end the thread and reclaim resources.&lt;br /&gt;- Get the current thread ID in the concurrent thread execution function.&lt;br /&gt;&lt;br /&gt;Next, I will take you to understand each function one by one.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;Create threads to execute custom functions concurrently&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;The ```__Thread``` function can create a thread and execute a function concurrently. For example, you need to create a concurrent function ```func1```, what does the ```func1``` function do? We can let it accumulate from 0 to 9. In order to see the gradual accumulation process, we use the for loop in the func1 function to pause each time (the Sleep function is used to sleep for a certain number of milliseconds) for a certain period of time.&lt;br /&gt;```&lt;br /&gt;function func1(sleepMilliseconds) {&lt;br /&gt;    var sum = 0 &lt;br /&gt;    for (var i = 0 ; i &amp;lt; 10 ; i++) {&lt;br /&gt;        sum += i &lt;br /&gt;        Sleep(sleepMilliseconds)&lt;br /&gt;        Log(&amp;quot;sum:&amp;quot;, sum)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    return sum&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    // Use the __Thread function to create a thread concurrently, and the parameter 200 is the parameter of the func1 function,&lt;br /&gt;    // If the func1 function has multiple parameters, here we pass the corresponding parameters.&lt;br /&gt;    var thread1Id = __Thread(func1, 200)&lt;br /&gt;    &lt;br /&gt;    // Here we need to wait for the execution result of the thread whose thread Id is thread1Id, otherwise all threads will be released directly after the main function is executed.&lt;br /&gt;    var ret = __threadJoin(thread1Id)&lt;br /&gt;    Log(&amp;quot;ret:&amp;quot;, ret)&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;In practical applications, we can make http requests concurrently like this:&lt;br /&gt;```&lt;br /&gt;function main() {&lt;br /&gt;    let threads = [&lt;br /&gt;        &amp;quot;https://www.baidu.com&amp;quot;,&lt;br /&gt;        &amp;quot;https://www.163.com&amp;quot;&lt;br /&gt;    ].map(function(url) {&lt;br /&gt;        return __Thread(function(url) {&lt;br /&gt;            Log(&amp;quot;GET&amp;quot;, url)&lt;br /&gt;            return HttpQuery(url)&lt;br /&gt;        }, url)&lt;br /&gt;    })&lt;br /&gt;    threads.forEach(function(tid) {&lt;br /&gt;        Log(__threadJoin(tid))&lt;br /&gt;    })&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;Wait for the end of thread execution to reclaim resources and return the execution result&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;In the above example, we used the ```__threadJoin``` function in the main function finally to wait for the concurrent threads to finish executing. The variable ```ret``` receives the return value of the ```__threadJoin``` function, and we print the return value, we can observe the specific results of the concurrent thread execution.&lt;br /&gt;```&lt;br /&gt;// id: thread ID, terminated: whether it was forced to stop, elapsed: time-consuming (nanoseconds), ret: the return value of the thread execution function&lt;br /&gt;ret: {&amp;quot;id&amp;quot;:1,&amp;quot;terminated&amp;quot;:false,&amp;quot;elapsed&amp;quot;:2004884301,&amp;quot;ret&amp;quot;:45}&lt;br /&gt;```&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;End the thread forcibly and reclaim resources&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;```&lt;br /&gt;function func1(sleepMilliseconds) {&lt;br /&gt;    var sum = 0 &lt;br /&gt;    for (var i = 0 ; i &amp;lt; 10 ; i++) {&lt;br /&gt;        sum += i &lt;br /&gt;        Sleep(sleepMilliseconds)&lt;br /&gt;        Log(&amp;quot;sum:&amp;quot;, sum)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    return sum&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    var thread1Id = __Thread(func1, 200)&lt;br /&gt;    Sleep(1000)&lt;br /&gt;    retThreadTerminate = __threadTerminate(thread1Id)&lt;br /&gt;    Log(retThreadTerminate)   // true&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;We still use the example just now, after creating a thread, you can forcibly terminate the execution of the thread after waiting for 1 second.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;Inter-thread communication&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Inter-thread communication mainly uses the ```__threadPostMessage``` function and the ```__threadPeekMessage``` function. Let&amp;#39;s look at the following simple example:&lt;br /&gt;```&lt;br /&gt;function func1() {&lt;br /&gt;    var id = __threadId()&lt;br /&gt;    while (true) {&lt;br /&gt;        var postMsg = &amp;quot;Message from thread function func1&amp;quot; with &amp;quot;from id:&amp;quot; + id + &lt;br /&gt;        __threadPostMessage(0, postMsg)              // Send a message to the main thread&lt;br /&gt;        var peekMsg = __threadPeekMessage()         // Receive messages from other threads&lt;br /&gt;        Log(peekMsg)&lt;br /&gt;        Sleep(5000)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    var threadId = __Thread(func1)&lt;br /&gt;    &lt;br /&gt;    while (true) {&lt;br /&gt;        var postMsg = &amp;quot;Messages from the main function of the main thread&amp;quot;&lt;br /&gt;        __threadPostMessage(threadId, postMsg)&lt;br /&gt;        var peekMsg = __threadPeekMessage(threadId)&lt;br /&gt;        Log(peekMsg, &amp;quot;#FF0000&amp;quot;)                     // #FF0000 , Set the log to red for distinction&lt;br /&gt;        Sleep(5000)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;The ```__threadPostMessage``` function is used to send a message to a thread. The first parameter is the ID of the specific thread to send to, and the second parameter is the message to be sent, which can be a string, a value, an array, or a JSON object and so on. Messages can be sent to the main thread in concurrent thread functions, and the ID of the main thread is defined as 0.&lt;br /&gt;&lt;br /&gt;The ```__threadPeekMessage``` function is used to monitor the message sent by a certain thread. It can set the timeout time (in milliseconds), or it can be set to 0, which means blocking, and it will not return until there is a message.&lt;br /&gt;&lt;br /&gt;Of course, except for concurrent threads communicating with the main thread. Concurrent threads can also communicate with each other directly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;Get the current thread ID in the concurrent thread execution function&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;In the above example, the function ```var id = __threadId()，__threadId()``` is used to get the ID of the current thread.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:140%"&gt;&lt;b&gt;Variables stored between shared threads&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;In addition to communication between threads, shared variables can also be used for interaction.&lt;br /&gt;```&lt;br /&gt;function testFunc() {&lt;br /&gt;    __threadSetData(0, &amp;quot;testFunc&amp;quot;, 100)   // Stored in the current thread environment, key-value pair testFunc : 100&lt;br /&gt;    Log(&amp;quot;testFunc execution completed&amp;quot;)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    // threadId is 1, the created thread with threadId 1 will be executed first, as long as the thread resources are not reclaimed, the variables stored locally in the thread will be valid&lt;br /&gt;    var testThread = __Thread(testFunc)&lt;br /&gt;    &lt;br /&gt;    Sleep(1000)&lt;br /&gt;&lt;br /&gt;    // export in main, get testFunc: 100&lt;br /&gt;    Log(&amp;quot;in main, get testFunc:&amp;quot;, __threadGetData(testThread, &amp;quot;testFunc&amp;quot;))   // Take out the value whose key name is testFunc&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;The above is a simple demonstration of all functions.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.ru/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y68da49bEAcF-zo9hFF6lkEJWdhFjJ4ccYcKl7IRkuOTs7C11E9GF8lT0470P8OtPdUL50g58AtwBpbuqpdtScjTEjOoX48E9Ar9S42SzA_feWM53nCw3Y7DAaH1z7JIDPUs_9FITfSaKbJPjK4jQxlE9yZdrpaK-hoLRg4N0I2xng9_9hdNqJg78qN60xQKmTRujvqLSzdfnG6IEENwJVQ0" title="https://blog.mathquant.com/2023/03/07/let-the-strategy-program-be-executed-concurrently-and-add-multi-thread-support-at-the-bottom-of-the-system-to-the-javascript-strategy.html"&gt;https://blog.mathquant.c...javascript-strategy.html&lt;/a&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
</feed>