자바스크립트 정책 디자인에서 _Thread 함수의 응용

저자:작은 꿈, 창작: 2023-07-04 16:35:42, 업데이트: 2023-09-18 19:32:51

img

자바스크립트 정책 디자인에서 _Thread 함수의 응용

초기 FMZ 정책 설계에서는 비동기 동시 동작을 사용할 필요가 있는 경우에만 사용할 수 있었다.exchange.Go()함수는 FMZ 포괄 인터페이스를 구현하기 위해 병행하여 사용자 정의 작업을 동시에 수행 할 수 없습니다. 이 디자인은 전략 프로그램이 실행되는 데 많은 효율성을 높여주는 반면, 원본 프로그래밍 언어에 병행 설계 경험이있는 동료는 매우 익숙하지 않습니다.

FMZ의 입학량 거래를 사용하는 신입생들조차도 이해하지 못합니다.exchange.Go()함수의 사용, 사용exchange.Go()이 글은 FMZ 플랫폼의 새로운 동행 스레드 기능에 대해 함께 탐구합니다.__Thread()예를 들어, 일련 함수의 사용과 전략 절차의 비동기 설계.

1, 간단한 동시 디자인

만약 우리가 메인 스레드를 실행하는 동시에 우리가 작성한 커스텀 함수를 실행하기 위해 하위 스레드를 실행하고 싶다면, 아래와 같은 코드를 사용할 수 있습니다.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)
    }
}

실제 디스크 실행 테스트:

img

이것은 가장 간단한 응용 프로그램 디자인입니다. 다음에는 다른 요구 디자인에 대해 살펴보겠습니다.

2, 단일 디자인

하나의 함수를 설계하여 10개의 스레드를 동시에 만들 수 있으며, 각각의 스레드는 하위 계열의 동작 함수를 수행한다.main()이 함수에서while루킹, 탐지 전략 상호작용 명령.placeMultipleOrders이 함수를 호출할 수 있습니다testPlaceMultipleOrders()

if (cmd == "placeMultipleOrders") {
    // ...
}

정책 편집 페이지에서 정책 상호 디자인 추가, 버튼을 설정, 명령어:placeMultipleOrders

img

전체 코드 예제:

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)
    }
}
  • 임팩트 방식으로 테스트, 현재 가격의 80% ~ 90%에서 증가, 아날로그 디스크 환경 테스트를 사용하여, 인터랙티브 버튼을 클릭하면 테스트를 실행합니다.

    img

  • "placeMultipleOrders" 버튼을 클릭하면 다음과 같은 메시지가 표시됩니다.

    img

  • 전략 로그에서는 다음과 같은 작업을 동시에 실행합니다:

    img

3, 동시 스레드 실행 함수에서 웹소켓 연결을 생성합니다.

이 요구는 FMZ 사용자에 의해 제안되었으며, 동시 스레드에서 사용하는 방법을 보여주는 간단한 예시를 희망합니다.웹소켓연결하고, 데이터를 메인 유선으로 전달하는 방법을 설계합니다.main()이 함수들은

실제로는 매우 간단하며, 이전 예제에서와 비슷한 동시다발적인 스레드를 생성합니다. 하지만 스레드 간 통신을 사용합니다.__threadPeekMessage()함수와__threadPostMessage()함수. 비트코인 거래소의 웹소켓 API 인터페이스 호출을 예로 들면, 디자인에서 우리는 웹소켓 연결의 종료 동작에 대해서도 주의를 기울여야 한다. 다음 예제에서도 동시다발적인 스레드에 알림을 주고 중지하도록 하는 방법을 보여준다.

전체 코드 예제:

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("扫尾函数执行完毕")
}

실제 디스크 실행 테스트:

img

이 사진들은main()함수는 동시로 만들어지는 스레드에서 웹소켓 연결에서 수신되는 트래픽 데이터를 지속적으로 수신합니다.

이 문서는 실제 디스크를 중지할 때 머리 함수가 작동합니다.

img


관련

더 많은

스파다 게임마지막 예시로, 만약 ws 스레드가 많고 여러 개의 주제를 구독하고 있다면, 스레드 간의 통신을 위해 get/set 방식이나 peek/post 방식을 사용하는 것이 더 좋은가요?

스파다 게임스레드 간의 공유 변수의 기본 구현은 참조 변수를 지원하지 않으며 업데이트 할 때마다 다시 설정해야합니다. 이것은 매우 비효율적입니다.

작은 꿈두 가지 방법이 다르지 않고, 모두 가능합니다.