Les ressources ont été chargées... Je charge...

Pour que les stratégies s'exécutent en parallèle, ajouter une prise en charge multi-threads au niveau inférieur du système pour les stratégies JavaScript.

Auteur:L'inventeur de la quantification - un petit rêve, Créé: 2023-03-02 14:19:15, Mis à jour: 2024-03-20 15:06:41

img

Pour que les stratégies s'exécutent en parallèle, ajouter une prise en charge multi-threads au niveau inférieur du système pour les stratégies JavaScript.

Lorsque vous développez des stratégies sur FMZ en utilisant le langage JavaScript, la structure des stratégies est consultée.exchange.GoLes fonctions utilisées pour effectuer des appels simultanés à certaines interfaces permettent de réaliser des scénarios simultanés.threadingIl y a aussi des sites web qui sont utilisés par les blogueurs pour créer des blogs.

Sur la base de ces besoins, la plateforme FMZ a mis à niveau la base du système.

  • Créer des threads en même temps pour exécuter des fonctions personnalisées
  • La communication entre les fils.
  • Les variables stockées entre les threads sont partagées.
  • Attendez que le fil d'exécution termine les ressources récupérées et renvoyez le résultat de l'exécution.
  • Les réseaux sociaux ont été détruits, les réseaux sociaux ont été détruits, les réseaux sociaux ont été détruits, les réseaux sociaux ont été détruits.
  • Obtenir l'ID du fil en cours dans une fonction d'exécution de fil en parallèle.

Les articles suivants vous aideront à comprendre chacune de ces fonctions.

Créer des fonctionnalités personnalisées en même temps que des fils

__ThreadLes fonctions peuvent créer un thread et exécuter une fonction en même temps. Par exemple, il est nécessaire de créer une fonction en parallèle.func1func1Que fait la fonction? On peut la faire passer de 0 à 9 en ajoutant une certaine quantité de millisecondes à la fonction sommeil.

function func1(sleepMilliseconds) {
    var sum = 0 
    for (var i = 0 ; i < 10 ; i++) {
        sum += i 
        Sleep(sleepMilliseconds)
        Log("sum:", sum)
    }
    
    return sum
}

function main() {
    // 使用__Thread函数并发创建一个线程,参数200即为func1函数的参数,
    // 如果func1函数有多个参数,这里就具体传对应的参数
    var thread1Id = __Thread(func1, 200)
    
    // 这里需要等待线程Id为thread1Id的线程执行结果,否则main函数执行完就直接释放所有线程
    var ret = __threadJoin(thread1Id)
    Log("ret:", ret)
}

Dans les scénarios d'application pratiques, nous pouvons exécuter des requêtes HTTP en parallèle comme ceci:

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))
    })
}

Attendez que le thread termine l'exécution pour récupérer les ressources et retourner les résultats d'exécution

Dans l'exemple ci-dessus, nous avons utilisé le dernier dans la fonction main.__threadJoinLes fonctions qui attendent l'exécution d'un thread en parallèle, les variablesretRéception__threadJoinLa valeur de retour de la fonction, que nous avons imprimée, est visible dans les résultats spécifiques de l'exécution de cette chaîne simultanée.

// id:线程ID,terminated:是否被强制停止,elapsed:耗时(纳秒),ret:线程执行函数的返回值
ret: {"id":1,"terminated":false,"elapsed":2004884301,"ret":45}

La fin forcée du fil et le recyclage des ressources

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
}

Dans l'exemple ci-dessus, après avoir créé un thread, vous pouvez forcer l'exécution du thread à s'arrêter après avoir attendu 1 seconde.

Communication entre les fils

Principalement utilisé pour la communication entre fils__threadPostMessageLes fonctions et__threadPeekMessageLes fonctions. Voyons un exemple simple:

function func1() {
    var id = __threadId()
    while (true) {
        var postMsg = "来自id:" + id + "的线程函数func1的消息"
        __threadPostMessage(0, postMsg)              // 发送消息到主线程
        var peekMsg = __threadPeekMessage()         // 接收来自其它线程的消息
        Log(peekMsg)
        Sleep(5000)
    }
}

function main() {
    var threadId = __Thread(func1)
    
    while (true) {
        var postMsg = "来自主线程的main函数的消息"
        __threadPostMessage(threadId, postMsg)
        var peekMsg = __threadPeekMessage()
        Log(peekMsg, "#FF0000")                     // #FF0000 , 设置日志为红色用于区分
        Sleep(5000)
    }
}

__threadPostMessageLes fonctions sont utilisées pour envoyer des messages à un certain thread, le premier paramètre étant l'ID spécifique du thread vers lequel le message est envoyé, le second paramètre étant le message envoyé, qui peut être une chaîne, une valeur numérique, un tableau, un objet JSON, etc. On peut envoyer des messages au thread principal dans une fonction de thread parallèle, dont l'ID est défini par 0.

__threadPeekMessageLes fonctions sont utilisées pour écouter les messages envoyés par un fil, peuvent être réglées sur le temps d'attente (millisecondes) ou sur 0 pour bloquer, et écouter jusqu'à ce qu'un message soit retourné.

Bien sûr, en plus de la communication entre les fils parallèles et les fils principaux, il est possible de communiquer directement entre les fils parallèles.

Obtenir l'ID du fil en cours dans une fonction d'exécution de fil en parallèle

Dans l'exemple ci-dessus, nous avons utilisévar id = __threadId()__threadId()Une fonction peut obtenir l'ID du fil en cours.

Variables stockées entre des threads partagés

En plus de la communication entre les fils, il est possible d'interagir avec des variables partagées.

function testFunc() {
    __threadSetData(0, "testFunc", 100)   // 储存在当前线程环境,键值对 testFunc : 100 
    Log("testFunc执行完毕")
}

function main() {
    // threadId为1 ,创建的threadId为1的线程会先执行完,只要线程资源没有被回收,线程本地储存的变量就有效
    var testThread = __Thread(testFunc)
    
    Sleep(1000)

    // 输出 in main, get testFunc: 100
    Log("in main, get testFunc:", __threadGetData(testThread, "testFunc"))   // 取出键名为testFunc的值
}

C'est une simple démonstration de toutes les fonctionnalités.


Relationnée

Plus de

Le couteau à osRépétez cette stratégie et exécutez le conseil: erreur ReferenceError: '__Thread' is not defined at main (__FILE__:5)

Le couteau à osLa collection et l'apprentissage

Inventeur de la quantificationMise à niveau du gestionnaire