Apabila membangunkan strategi di FMZ menggunakan bahasa JavaScript, kerana seni bina strategi diundi.exchange.Go
fungsi digunakan untuk membuat panggilan serentak ke beberapa antara muka, supaya memenuhi keperluan beberapa senario serentak. tetapi jika anda ingin membuat satu benang untuk melakukan satu siri operasi, ia adalah mustahil. contohnya seperti bahasa Python, gunakanthreading
perpustakaan untuk melakukan beberapa reka bentuk serentak.
Berdasarkan keperluan ini, platform FMZ telah menaik taraf lapisan bawah sistem. Sokongan multithreading sejati juga telah ditambah ke dalam bahasa JavaScript. Ciri terperinci termasuk:
Seterusnya, saya akan membawa anda untuk memahami setiap fungsi satu demi satu.
Peraturan__Thread
fungsi boleh mencipta benang dan melaksanakan fungsi serentak.func1
, apa yangfunc1
Untuk melihat proses pengumpulan secara beransur-ansur, kita menggunakan gelung for dalam fungsi func1 untuk berehat setiap kali (fungsi Sleep digunakan untuk tidur untuk beberapa milidetik) untuk tempoh masa tertentu.
function func1(sleepMilliseconds) {
var sum = 0
for (var i = 0 ; i < 10 ; i++) {
sum += i
Sleep(sleepMilliseconds)
Log("sum:", sum)
}
return sum
}
function main() {
// Use the __Thread function to create a thread concurrently, and the parameter 200 is the parameter of the func1 function,
// If the func1 function has multiple parameters, here we pass the corresponding parameters.
var thread1Id = __Thread(func1, 200)
// 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.
var ret = __threadJoin(thread1Id)
Log("ret:", ret)
}
Dalam aplikasi praktikal, kita boleh membuat permintaan http serentak seperti ini:
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))
})
}
Dalam contoh di atas, kita menggunakan__threadJoin
fungsi dalam fungsi utama akhirnya untuk menunggu untuk utas serentak untuk menyelesaikan pelaksanaan.ret
menerima nilai pulangan__threadJoin
fungsi, dan kita cetak nilai pulangan, kita boleh memerhatikan hasil tertentu dari pelaksanaan benang serentak.
// id: thread ID, terminated: whether it was forced to stop, elapsed: time-consuming (nanoseconds), ret: the return value of the thread execution function
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
}
Kami masih menggunakan contoh sekarang, selepas membuat utas, anda boleh memaksa menamatkan pelaksanaan utas selepas menunggu selama 1 saat.
Komunikasi antara benang terutamanya menggunakan__threadPostMessage
fungsi dan__threadPeekMessage
Mari kita lihat contoh mudah berikut:
function func1() {
var id = __threadId()
while (true) {
var postMsg = "Message from thread function func1" with "from id:" + id +
__threadPostMessage(0, postMsg) // Send a message to the main thread
var peekMsg = __threadPeekMessage(0) // Receive messages from the main thread
Log(peekMsg)
Sleep(5000)
}
}
function main() {
var threadId = __Thread(func1)
while (true) {
var postMsg = "Messages from the main function of the main thread"
__threadPostMessage(threadId, postMsg)
var peekMsg = __threadPeekMessage(threadId)
Log(peekMsg, "#FF0000") // #FF0000 , Set the log to red for distinction
Sleep(5000)
}
}
Peraturan__threadPostMessage
fungsi digunakan untuk menghantar mesej ke thread. Parameter pertama adalah ID thread tertentu untuk dihantar, dan parameter kedua adalah mesej yang akan dihantar, yang boleh menjadi rentetan, nilai, array, atau objek JSON dan sebagainya. Mesej boleh dihantar ke thread utama dalam fungsi thread serentak, dan ID thread utama ditakrifkan sebagai 0.
Peraturan__threadPeekMessage
fungsi digunakan untuk memantau mesej yang dihantar oleh utas tertentu. Parameter pertama adalah untuk memantau ID khusus utas. Parameter kedua boleh menetapkan masa tamat (dalam mili saat), atau ia boleh ditetapkan kepada -1, yang bermaksud menyekat, dan ia tidak akan kembali sehingga ada mesej. Kita boleh mendengar mesej yang dihantar oleh utas utama ke utas semasa dalam fungsi utas serentak, dan ID utas utama ditakrifkan sebagai 0.
Sudah tentu, kecuali untuk benang serentak yang berkomunikasi dengan benang utama. benang serentak juga boleh berkomunikasi antara satu sama lain secara langsung.
Dalam contoh di atas,var id = __threadId()
digunakan, dan__threadId()
fungsi boleh mendapatkan ID benang semasa.
Sebagai tambahan kepada komunikasi antara benang, pembolehubah bersama juga boleh digunakan untuk interaksi.
function testFunc() {
__threadSetData(0, "testFunc", 100) // Stored in the current thread environment, key-value pair testFunc : 100
Log("testFunc execution completed")
}
function main() {
// 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
var testThread = __Thread(testFunc)
Sleep(1000)
// export in main, get testFunc: 100
Log("in main, get testFunc:", __threadGetData(testThread, "testFunc")) // Take out the value whose key name is testFunc
}
Yang di atas adalah demonstrasi mudah semua fungsi. mari kita lihat contoh ujian yang sedikit lebih rumit.
Alamat strategi ujian ini:https://www.fmz.com/strategy/401463
Pada pandangan pertama, anda mungkin tidak tahu apa yang dilakukan strategi ujian ini. Tidak penting, mari kita jelaskannya. Pertama, mari belajar apa itu WASM.
Then the test strategy is to compare the execution efficiency of wasm and javascript, but when comparing, the two execution methods can be executed successively, and the time-consuming of each is counted. It is also possible to allow the two execution methods to execute concurrently, and the statistics are time-consuming. Now that the underlying concurrency implementation of the JavaScript language strategy has been supported, the test strategy uses a concurrent method to compare naturally and compare the execution speed of the same algorithm.
- Algorithm of C language version, fib function
// Algoritma rekursif nombor Fibonacci dalam Bahasa C int fib ((int f) { jika (f < 2) pulangkan f; pulangkan fib ((f - 1) + fib ((f - 2); {}
- JavaScript language version of the algorithm, fib function
// Algoritma rekursif untuk nombor Fibonacci yang sama, ditulis dalam JavaScript fungsi fib ((f) { jika (f < 2) mengembalikan f pulangkan fib ((f - 1) + fib ((f - 2) {}
It can be seen that the logic of the two fib function algorithms is exactly the same. The following is the source code of the test strategy:
Fungsi utama
// Untuk memudahkan anda melihat kod, saya menulis komen pada kod berikut secara langsung:
let cycle = 100 // Ujian menjalankan gelung 100 kali
let input = 30 // Parameter yang akan dihantar kepada fungsi algoritma fib
biar benang = [
__Thread(function(cycle, input) { // Thread dicipta serentak untuk melakukan pengiraan menggunakan versi JavaScript fungsi fib
fungsi fib ((f) { // Algoritma tertentu yang digunakan untuk ujian, fungsi fib
jika (f < 2) mengembalikan f
pulangkan fib ((f - 1) + fib ((f - 2)
{}
let ret = 0
untuk (biarkan i = 0; i < kitaran; i++) { // gelung untuk 100 kali
ret = fib(input); // Panggil fungsi fib bahasa JavaScript
Log ((
__Thread(function(cycle, input) { // Run a thread concurrently to perform calculations using the wasm version of the fib function
let data = 'data:hex,0061736d010000000186808080000160017f017f0382808080000100048480808000017000000583808080000100010681808080000007908080800002066d656d6f727902000366696200000aa480808000019e80808000000240200041024e0d0020000f0b2000417f6a10002000417e6a10006a0b'
let m = wasm.parseModule(data) // The data variable is the hex string of the wasm-encoded C language fib function, and the wasm model m is created using wasm.parseModule
let instance = wasm.buildInstance(m, { // Model instantiation, allocate a certain stack space
stack_size: 65 * 1024 * 1024,
})
let ret = 0
for (let i = 0; i < cycle; i++) { // loop for 100 times
ret = instance.callFunction('fib', input) // Calling the fib function code in the wasm instance is equivalent to calling the int fib(int f) function
Log("wasm progress: ", i)
}
return 'wasm fib: ' + ret
}, cycle, input)
]
// The elements in the threads array are the IDs returned by the __Thread function
threads.forEach(function(tid) {
let info = __threadJoin(tid) // Use the __threadJoin function to wait for two concurrent threads to execute and get the execution result
Log('#'+tid, info.ret, 'elapsed:', info.elapsed / 1e6, "#ff0000") // output execution result
})
}
Simply put, WASM is a program code with higher execution efficiency. In the example, we convert the c language code of "Fibonacci number recursive algorithm" into WASM. The process is like this:
1. Compile a piece of C language function code into wasm code.
We can use the website to convert: https://wasdk.github.io/WasmFiddle/
// Algoritma rekursif nombor Fibonacci dalam Bahasa C int fib ((int f) { jika (f < 2) pulangkan f; pulangkan fib ((f - 1) + fib ((f - 2); {}
2. Further encode the wasm code into a hex string.
The following commands can be used:
python -c
The encoded hex string is ```let data = 'data:hex,0061736d0100000001868...``` in the code.
3. Then parse it into a wasm model through the function ```wasm.parseModule()``` integrated by FMZ.
4. Create a wasm model instance through the function ```wasm.buildInstance()``` integrated by FMZ.
5. Then call the ```fib``` function in this wasm model instance, namely: ```ret = instance.callFunction('fib', input)```.
## Create a real bot to run the test
This test strategy can only be used for real bot testing. JavaScript multi-threading functions do not support backtesting so far.
```wasm``` and ```JavaScript``` execution comparison, the final execution results:
2023-03-06 11:00:33 infomation #2 wasm fib: 832040 telah berlalu: 13283.773019
2023-03-06 11:00:33 infomation #1 javascript fib: 832040 telah berlalu: 21266.326974
It seems that
Wasm