
اصل FMZ حکمت عملی کے ڈیزائن میں، اگر آپ کو غیر متزلزل کنکرنٹ آپریشنز استعمال کرنے کی ضرورت ہے، تو آپ صرف استعمال کر سکتے ہیںexchange.Go()فنکشن کا استعمال FMZ encapsulation انٹرفیس کی ہم آہنگی کو نافذ کرنے کے لیے کیا جاتا ہے، اور کچھ کسٹم آپریشنز (فنکشنز) کو بیک وقت انجام نہیں دیا جا سکتا۔ اگرچہ یہ ڈیزائن پالیسی پروگرام پر عمل درآمد کی کارکردگی کو بہت بہتر بناتا ہے، لیکن یہ اب بھی ان طلبا کے لیے بہت ناواقف ہے جنہیں مقامی پروگرامنگ زبانوں میں ایک ساتھ ڈیزائن کا تجربہ ہے۔
یہاں تک کہ کچھ نئے طلباء جو FMZ کا استعمال کرتے ہوئے مقداری تجارت میں نئے ہیں وہ نہیں سمجھتے ہیں۔exchange.Go()افعال کا استعمال، استعمالexchange.Go()ایسا اب بھی لگتا ہے کہ ترتیب وار کوڈ میں بیانات کو ایک ایک کر کے عمل میں لایا جاتا ہے۔ اس آرٹیکل میں، آئیے FMZ پلیٹ فارم کی نئی کنکرنٹ تھریڈنگ خصوصیات کو دریافت کریں:__Thread()افعال اور حکمت عملی پروگرام غیر مطابقت پذیر ڈیزائن کی ایک سیریز کا استعمال۔
اگر ہم ایک چائلڈ تھریڈ کو ایک ساتھ چلانا چاہتے ہیں تاکہ ایک حسب ضرورت فنکشن کو عمل میں لایا جائے جو ہم نے اسٹریٹیجی مین تھریڈ کے چلنے کے دوران لکھا تھا، تو ہم مندرجہ ذیل کوڈ سے ملتا جلتا ڈیزائن استعمال کر سکتے ہیں۔ حکمت عملی کوڈ میں فنکشن کو اپنی مرضی کے مطابق بنائیںGetTickerAsync()، اس فنکشن کی مخصوص فعالیت لکھیں۔ یہ فنکشن ایک لامحدود لوپ کو چلاتا ہے۔whileFMZ API انٹرفیس کو مسلسل ایک لوپ میں کہا جاتا ہے:GetTicker()مارکیٹ ڈیٹا حاصل کرنے کے لیے۔
پھر استعمال کریں۔__threadSetData(0, "ticker", t)یہ جملہ مرکزی دھاگے میں ڈیٹا لکھتا ہے۔ticker، ڈیٹا ویلیو ہے۔tابھیGetTicker()کی واپسی کی قدر
__threadSetData(0, "ticker", t)
دھاگوں کے ایک ساتھ عمل درآمد کے لیے کسٹم فنکشن کو ڈیزائن کرنے کے بعد، ہم لکھ سکتے ہیں۔main()فنکشن میں کوڈ ہے۔main()فنکشن کے آغاز میں، ہم استعمال کرتے ہیں:
__Thread(GetTickerAsync, 0) // GetTickerAsync为需要并发执行的自定义函数,0为这个传入GetTickerAsync函数的参数
ایک سمورتی دھاگہ بنائیں، جس پر عمل درآمد شروع ہو جائے۔GetTickerAsync()فنکشن پھرmain()فنکشن اس پر عمل درآمد شروع کرتا ہے۔whileلوپ، لوپ میں وصول کریںGetTickerAsync()فنکشن ڈیٹا کو اپ ڈیٹ کرتا ہے اور پھر پرنٹ کرتا ہے:
var t = __threadGetData(0, "ticker")
Log(t)
مکمل کوڈ کی مثال:
function GetTickerAsync(index) {
while (true) {
var t = exchanges[index].GetTicker()
__threadSetData(0, "ticker", t)
Sleep(500)
}
}
function main() {
__Thread(GetTickerAsync, 0)
while(true) {
var t = __threadGetData(0, "ticker")
Log(t)
Sleep(1000)
}
}
اصلی ڈسک آپریشن ٹیسٹ:

یہ سب سے آسان ایپلیکیشن ڈیزائن ہے، آئیے کچھ دیگر ڈیمانڈ ڈیزائنز کو دیکھتے ہیں۔
ایک فنکشن کو ایک ہی وقت میں 10 تھریڈز بنانے کے لیے ڈیزائن کیا جا سکتا ہے، اور ہر تھریڈ آرڈر آپریشن فنکشن کو انجام دیتا ہے۔ موجودmain()ایک فنکشن ڈیزائن کریں۔whileلوپ، پتہ لگانے کی حکمت عملی کے تعامل کی ہدایات۔ انٹرایکٹو ہدایات حاصل کریں:placeMultipleOrdersبس اس سمورتی آرڈر فنکشن کو کال کریں۔testPlaceMultipleOrders()。
if (cmd == "placeMultipleOrders") {
// ...
}
حکمت عملی میں ترمیم کرنے والے صفحہ پر حکمت عملی کے تعامل کا ڈیزائن شامل کریں اور کمانڈ کے ساتھ ایک بٹن سیٹ کریں: placeMultipleOrders

مکمل کوڈ کی مثال:
function placeOrder(exIndex, type, price, amount) {
var id = null
if (type == "Buy") {
id = exchanges[exIndex].Buy(price, amount)
} else if (type == "Sell") {
id = exchanges[exIndex].Sell(price, amount)
} else {
throw "type error! type:" + type
}
}
function testPlaceMultipleOrders(index, beginPrice, endPrice, step, type, amount) {
Log("beginPrice:", beginPrice, ", endPrice:", endPrice, ", step:", step, ", type:", type, ", amount:", amount)
var tids = []
for (var p = beginPrice; p <= endPrice; p += step) {
var tid = __Thread(placeOrder, index, type, p, amount)
tids.push(tid)
Sleep(10)
}
Sleep(1000)
for (var i = 0; i < tids.length; i++) {
__threadTerminate(tids[i])
}
}
function main() {
while(true) {
LogStatus(_D())
var cmd = GetCommand()
if (cmd) {
if (cmd == "placeMultipleOrders") {
var t = _C(exchange.GetTicker)
var beginPrice = t.Last * 0.8
var endPrice = t.Last * 0.9
var step = t.Last * 0.01
testPlaceMultipleOrders(0, beginPrice, endPrice, step, "Buy", 0.01)
var orders = exchange.GetOrders()
for (var i = 0; i < orders.length; i++) {
Log(orders[i])
}
}
}
Sleep(1000)
}
}



یہ ضرورت ایک FMZ صارف کی طرف سے اٹھائی گئی تھی جو ایک سادہ سی مثال چاہتا تھا کہ یہ ظاہر کرے کہ اسے کنکرنٹ تھریڈز میں کیسے استعمال کیا جائے۔WebSocketجڑیں اور ڈیزائن کریں کہ ڈیٹا کو مین تھریڈ میں کیسے منتقل کیا جائے۔main()فنکشن
یہ درحقیقت بہت آسان ہے، اور پچھلی مثال میں سمورتی تھریڈز بنانے کے مترادف ہے۔ صرف دھاگوں کے درمیان رابطے کا استعمال کیا جاتا ہے۔__threadPeekMessage()افعال اور__threadPostMessage()فنکشن بائننس ایکسچینج کی WebSocket API انٹرفیس کال کو مثال کے طور پر لیتے ہوئے، ہمیں ڈیزائن میں WebSocket کنکشن کے اختتامی عمل پر بھی توجہ دینے کی ضرورت ہے۔
مکمل کوڈ کی مثال:
var tid = null
function createWS() {
// wss://stream.binance.com:9443/ws/<streamName> , <symbol>@ticker
var stream = "wss://stream.binance.com:9443/ws/btcusdt@ticker"
var ws = Dial(stream)
Log("创建WS连接:", stream)
while (true) {
var data = ws.read()
if (data) {
__threadPostMessage(0, data)
}
Log("接收到WS链接推送的数据,data:", data)
// __threadPeekMessage 超时参数设置-1,不阻塞
var msg = __threadPeekMessage(-1)
if (msg) {
if (msg == "stop") {
Log("并发线程Id:", __threadId(), "接收到stop指令")
break
}
}
}
Log("并发线程执行完毕,关闭ws连接")
ws.close()
}
function main() {
tid = __Thread(createWS)
Log("创建并发线程,线程Id:", tid)
while(true) {
// __threadPeekMessage 的超时参数设置为0,阻塞等待数据
var data = __threadPeekMessage(0)
Log("接收到并发线程", ", Id:", tid, ", 发送的数据,data:", data, "#FF0000")
var tbl = {
type : "table",
title : "<symbol>@ticker频道推送消息",
cols : ["事件类型", "事件时间", "交易对", "24小时价格变化", "24小时价格变化百分比", "平均价格", "最新成交价格", "24小时内成交量", "24小时内成交额"],
rows : []
}
try {
data = JSON.parse(data)
tbl.rows.push([data.e, _D(data.E), data.s, data.p, data.P, data.w, data.c, data.v, data.q])
} catch (e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
}
}
function onexit() {
Log("扫尾函数,向Id为", tid, "的并发线程发送stop指令")
__threadPostMessage(tid, "stop")
Log("等待Id为", tid, "的并发线程停止")
__threadJoin(tid)
Log("扫尾函数执行完毕")
}
اصلی ڈسک آپریشن ٹیسٹ:

آپ دیکھ سکتے ہیں۔main()یہ فنکشن کنکرنٹ تھریڈ کے ذریعہ بنائے گئے WebSocket کنکشن سے مسلسل مارکیٹ ڈیٹا حاصل کرتا ہے۔
جب حکمت عملی روک دی جائے گی، تو سویپ فنکشن کام کرنا شروع کر دے گا:
