The threading
object is a global multithreading management tool that provides functions such as creating concurrent threads, thread locks, and condition objects. This section introduces the member functions of the threading
object. This object is only supported by the JavaScript
language strategy.
The Thread()
function is used to create concurrent threads.
The Thread()
function returns a Thread
object, which is used to manage created concurrent threads, thread communication, etc.
Thread(func, ...args)
Thread(...items)
The parameter ```func``` is a function for concurrent execution (passed by reference), and supports passing in anonymous functions. ```func``` can accept multiple parameters, which will be passed in through ```...args``` during concurrent execution. Therefore, the parameter list of ```func``` needs to be consistent with ```...args```.
func
true
function
The parameter ```arg``` is the actual parameter passed to ```func``` (i.e. the concurrent thread execution function) when the callback is executed; there may be multiple parameters ```arg```, and the parameter list of ```func``` needs to be consistent with ```...args```.
arg
false
string, number, bool, object, array, function, null value and other types supported by the system
The parameter ```item``` is an array containing the function references and their parameters to be executed concurrently. Multiple groups of ```item``` parameters can be passed in when calling the ```Thread``` function.
item
true
array
```javascript
function test1(a, b, c) {
Log("test1:", a, b, c)
}
function main() {
var t1 = threading.Thread(test1, 1, 2, 3)
var t2 = threading.Thread(function (msg) {
Log("msg:", msg)
}, "Hello thread2")
t1.join()
t2.join()
}
Create concurrent threads for both a custom function and an anonymous function.
function test1(msg) {
Log("msg:", msg)
test2("Hello test2")
}
function main() {
var t1 = threading.Thread(
[function(a, b, c) {Log(a, b, c)}, 1, 2, 3],
[test1, "Hello test1"],
[`function test2(msg) {Log("msg:", msg)}`])
t1.join()
}
Use the Thread(...items)
form to create concurrent threads and execute multiple functions sequentially.
function testFunc1(p) {
Log("testFunc1 p:", p)
}
function main() {
threading.Thread(function(pfn) {
var threadName = threading.currentThread().name()
var threadId = threading.currentThread().id()
pfn(`in thread threadName: ${threadName}, threadId: ${threadId}`)
}, testFunc1).join()
}
It supports passing parameters to concurrently executed functions.
function ml(input) {
const net = new brain.NeuralNetwork()
net.train([
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [0] },
])
return net.run(input)
}
function main() {
var ret = threading.Thread([ml, [1, 0]], [HttpQuery("https://unpkg.com/brain.js")]).join()
// ret: {"id":1,"terminated":false,"elapsed":337636000,"ret":{"0":0.9339330196380615}}
Log(ret)
}
It supports passing in function strings and can import external libraries dynamically for concurrent computing.
The thread function func
passed into the Thread()
function for concurrent execution runs in an isolated environment, so variables outside the thread cannot be directly referenced, and compilation will fail when referenced. At the same time, references to other closure functions are not supported within the thread. All APIs provided by the platform can be called within the thread, but other user-defined functions cannot be called.
When a thread is executed and is not referenced continuously, the underlying system will reclaim thread-related resources automatically, and there is no need to explicitly call the join()
function to release resources. If there is a continuous reference that prevents the release of resources, an error will be reported if the number of concurrent calls exceeds 2000: InternalError: too many routine wait, max is 2000
.
It supports backtesting system and live trading environment. All concurrent thread-related functions are only supported as code compatibility in the backtesting system and will not be actually executed by concurrent threads, so they will not be repeated in this chapter.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The getThread()
function is used to get the thread object based on the specified thread Id.
The getThread()
function returns the Thread
object with the threadId specified by the parameter
getThread(threadId)
The parameter ```threadId``` is the thread object ID. Get the corresponding thread object by specifying the parameter.
threadId
true
number
```javascript
function main() {
var t1 = threading.Thread(function () {
// The Thread object has a method: id(), which is used to get the thread ID. You can view the section of the document corresponding to the Thread object.
var id = threading.currentThread().id()
var thread1 = threading.getThread(id)
Log("id:", id, ", thread1.id():", thread1.id())
Log(`id == thread1.id():`, id == thread1.id())
})
t1.join()
Log("Hello thread1")
})
// The Thread object has a method: id(), which is used to get the thread ID. You can view the section of the document corresponding to the Thread object.
var threadId = t1.id()
var threadName = t1.name()
Log("threadId:", threadId, ", threadName:", threadName)
var t2 = threading.getThread(threadId)
Log(`threadId == t2.id():`, threadId == t2.id(), `, threadName == t2.name():`, threadName == t2.name())
}
Get the specified thread object through threadId
.
It supports backtesting system and live trading environment.
If the thread you want to obtain has been executed and released, you cannot use threading.getThread(threadId)
to obtain the thread object of the thread.
{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The mainThread()
function is used to obtain the thread object of the main thread, that is, the thread where the main()
function in the strategy is located.
The mainThread()
function returns the thread object of the main thread.
mainThread()
```javascript
function main() {
Log("The threadId of the main thread:", threading.mainThread().id())
}
Get the Thread
object of the main thread and output the threadId
of the main thread.
function test() {
Log("Output the main thread ID in the test function:", threading.mainThread().id())
}
function main() {
var t1 = threading.Thread(test)
t1.join()
}
The thread object of the main thread can also be obtained in concurrent threads.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The currentThread()
function is used to get the thread object of the current thread.
The currentThread()
function returns the thread object of the current thread.
currentThread()
```javascript
function test() {
Log("Id of the current thread:", threading.currentThread().id())
}
function main() {
var t1 = threading.Thread(test)
t1.join()
}
Get the Thread
object of the current thread and output the threadId
of the current thread.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Lock()
function is used to create a thread lock object.
The Lock()
function returns a thread lock object.
Lock()
```javascript
function consumer(productionQuantity, dict, lock) {
for (var i = 0; i < productionQuantity; i++) {
lock.acquire()
var count = dict.get("count")
Log("consumer:", count)
Sleep(1000)
lock.release()
}
}
function producer(productionQuantity, dict, lock) {
for (var i = 0; i < productionQuantity; i++) {
lock.acquire()
dict.set("count", i)
Log("producer:", i)
Sleep(1000)
lock.release()
}
}
function main() {
var dict = threading.Dict()
dict.set("count", -1)
var lock = threading.Lock()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, lock)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, lock)
consumerThread.join()
producerThread.join()
}
Two concurrent threads access a common resource.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Condition()
function is used to create a condition variable object, which is used to achieve synchronization and communication between threads in a multi-threaded concurrent environment. Through Condition()
, a thread can wait when certain conditions are not met until another thread notifies it that the condition has been met.
The Condition()
function returns a ThreadCondition
object.
Condition()
```javascript
function consumer(productionQuantity, dict, condition) {
for (var i = 0; i < productionQuantity; i++) {
condition.acquire()
while (dict.get("array").length == 0) {
condition.wait()
}
var arr = dict.get("array")
var count = arr.shift()
dict.set("array", arr)
Log("consumer:", count, ", array:", arr)
condition.release()
Sleep(1000)
}
}
function producer(productionQuantity, dict, condition) {
for (var i = 0; i < productionQuantity; i++) {
condition.acquire()
var arr = dict.get("array")
arr.push(i)
dict.set("array", arr)
Log("producer:", i, ", array:", arr)
condition.notify()
condition.release()
Sleep(1000)
}
}
function main() {
var dict = threading.Dict()
dict.set("array", [])
var condition = threading.Condition()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, condition)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, condition)
consumerThread.join()
producerThread.join()
}
Two concurrent threads access a common resource.
The backtesting system does not implement this functionality, it only defines it.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Event()
function is used to create a thread event object, which is used for synchronization between threads, allowing one thread to wait for notification or signal from another thread.
The Event()
function returns a ThreadEvent
object.
Event()
```javascript
function consumer(productionQuantity, dict, pEvent, cEvent) {
for (var i = 0; i < productionQuantity; i++) {
while (dict.get("array").length == 0) {
pEvent.wait()
}
if (pEvent.isSet()) {
pEvent.clear()
}
var arr = dict.get("array")
var count = arr.shift()
dict.set("array", arr)
Log("consumer:", count, ", array:", arr)
cEvent.set()
Sleep(1000)
}
}
function producer(productionQuantity, dict, pEvent, cEvent) {
for (var i = 0; i < productionQuantity; i++) {
while (dict.get("array").length != 0) {
cEvent.wait()
}
if (cEvent.isSet()) {
cEvent.clear()
}
var arr = dict.get("array")
arr.push(i)
dict.set("array", arr)
Log("producer:", i, ", array:", arr)
pEvent.set()
Sleep(1000)
}
}
function main() {
var dict = threading.Dict()
dict.set("array", [])
var pEvent = threading.Event()
var cEvent = threading.Event()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, pEvent, cEvent)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, pEvent, cEvent)
consumerThread.join()
producerThread.join()
}
Two concurrent threads access a common resource.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Dict()
function is used to create a dictionary object for passing to concurrent threads.
The Dict()
function returns a ThreadDict
object.
Dict()
```javascript
function threadFun1(obj) {
obj["age"] = 100
while (true) {
Log("threadFun1 obj:", obj)
Sleep(5000)
}
}
function threadFun2(obj) {
while (true) {
Log("threadFun2 obj:", obj)
Sleep(5000)
}
}
function main() {
var obj = {"age": 10}
var t1 = threading.Thread(threadFun1, obj)
var t2 = threading.Thread(threadFun2, obj)
t1.join()
t2.join()
}
Pass a normal object to the concurrent thread execution function to test whether modifying the key value of the object will cause changes in the key value of the object in other threads.
function threadFun1(threadDict) {
threadDict.set("age", 100)
while (true) {
Log(`threadFun1 threadDict.get("age"):`, threadDict.get("age"))
Sleep(5000)
}
}
function threadFun2(threadDict) {
while (true) {
Log(`threadFun2 threadDict.get("age"):`, threadDict.get("age"))
Sleep(5000)
}
}
function main() {
var threadDict = threading.Dict()
threadDict.set("age", 10)
var t1 = threading.Thread(threadFun1, threadDict)
var t2 = threading.Thread(threadFun2, threadDict)
t1.join()
t2.join()
}
Pass the ThreadDict
object created by the Dict()
function to the concurrent thread execution function, and test whether modifying the key value of the object will cause the key value of the object in other threads to change.
When a common object is passed to a concurrent thread function, it is passed as a deep copy. Modifying the key value in a concurrent thread will not affect the dictionary in other threads.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The pending
function is used to obtain the number of concurrent threads running in the current strategy program.
The pending()
function returns the number of concurrent threads that the current strategy program is running.
number
pending()
function threadFun1() {
Log("threadFun1")
Sleep(3000)
}
function threadFun2() {
for (var i = 0; i < 3; i++) {
LogStatus(_D(), "print from threadFun2")
Sleep(3000)
}
}
function main() {
Log(`begin -- threading.pending():`, threading.pending())
var t1 = threading.Thread(threadFun1)
var t2 = threading.Thread(threadFun2)
Log(`after threading.Thread -- threading.pending():`, threading.pending())
t1.join()
t2.join()
Log(`after thread.join -- threading.pending():`, threading.pending())
}
Create two concurrently running threads and call the pending()
function at different time nodes.
When the strategy main()
function starts running, calling the function pending()
directly will return 1, because the main thread where the strategy main()
function is located is also a pending thread.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/eventLoop eventLoop}
NetSettings Thread