Membuat program dasar benar-benar dijalankan secara serentak, menambah sokongan pelbagai benang di dasar sistem untuk dasar JavaScript

Penulis:Mimpi kecil, Dicipta pada: 2023-03-02 14:19:15, Dikemas kini pada: 2024-03-20 15:06:41

img

Membuat program dasar benar-benar dijalankan secara serentak, menambah sokongan pelbagai benang di dasar sistem untuk dasar JavaScript

Apabila menggunakan bahasa JavaScript untuk membangunkan dasar di FMZ, kerana struktur dasar adalah rundingan; jika terdapat senario yang dirancang secara serentak, ia adalah melaluiexchange.GoFungsi untuk melakukan panggilan serentak beberapa antara muka, sehingga memenuhi keperluan beberapa senario serentak. Tetapi tidak dapat dilaksanakan jika ingin membuat satu benang secara berasingan untuk melakukan satu siri operasi, seperti bahasa Python, menggunakanthreadingSaya telah membuat beberapa reka bentuk serentak.

Berdasarkan keperluan ini, FMZ platform menaik taraf asas sistem. Ia juga menambah sokongan multi-threaded sebenar untuk bahasa JavaScript. Fungsi terperinci termasuk:

  • Mencipta benang pada masa yang sama untuk menjalankan fungsi tersuai.
  • Komunikasi antara benang.
  • Variabel yang disimpan di antara benang yang dikongsi.
  • Menunggu untuk menjalankan thread untuk menamatkan sumber pemulihan dan mengembalikan hasil pelaksanaan.
  • "Mengharuskan sambungan dan mengitar semula sumber".
  • Mendapatkan ID benang semasa dalam fungsi pelaksanaan benang yang disatukan.

Di bawah ini, kami akan memaparkan cara anda memahami setiap fungsi secara individu.

Mencipta fungsi tersuai untuk dijalankan pada masa yang sama

__ThreadFungsi boleh mencipta satu benang dan menjalankan satu fungsi secara serentak. Sebagai contoh, memerlukan penciptaan fungsi serentak.func1func1Apakah fungsi ini berfungsi? Kita boleh membuat ia bertambah dari 0 kepada 9, untuk melihat proses penambahan secara beransur-ansur ini, kita boleh menggunakan for loop dalam fungsi func1 untuk menghentikan setiap kali (fungsi tidur digunakan untuk tidur beberapa milidetik) 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() {
    // 使用__Thread函数并发创建一个线程,参数200即为func1函数的参数,
    // 如果func1函数有多个参数,这里就具体传对应的参数
    var thread1Id = __Thread(func1, 200)
    
    // 这里需要等待线程Id为thread1Id的线程执行结果,否则main函数执行完就直接释放所有线程
    var ret = __threadJoin(thread1Id)
    Log("ret:", ret)
}

Dalam kes penggunaan sebenar, kita boleh melakukan permintaan HTTP secara 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))
    })
}

Menunggu untuk menjalankan thread untuk menamatkan sumber pemulihan dan mengembalikan hasil pelaksanaan

Dalam contoh di atas, kita akan gunakan fungsi utama untuk terakhir kalinya.__threadJoinFungsi untuk menunggu tamatnya pelaksanaan utas serentak, pemboleh ubahretMenerima__threadJoinNilai pulangan fungsi, kita cetak nilai pulangan ini, dan kita boleh melihat hasil tertentu dari pelaksanaan utas serentak ini.

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

Memaksa penutupan dan mengumpul semula sumber

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
}

Atau, sebagai contoh yang baru-baru ini, selepas membuat utas, anda boleh memaksa penamatan tamat selepas menunggu 1 saat.

Komunikasi antara benang

Komunikasi antara benang digunakan terutamanya__threadPostMessageFungsi dan__threadPeekMessageFungsi. Mari kita lihat contoh mudah berikut:

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

__threadPostMessageFungsi digunakan untuk menghantar mesej kepada suatu utas, parameter pertama adalah ID khusus untuk mana utas yang dihantar, parameter kedua adalah mesej yang dihantar, boleh menjadi rentetan, nilai, array, objek JSON, dan lain-lain. Fungsi boleh menghantar mesej kepada utas utama dalam fungsi utas serentak, ID utas utama ditakrifkan sebagai 0.

__threadPeekMessageFungsi ini digunakan untuk memantau mesej yang dihantar oleh satu benang, boleh menetapkan masa lama (millisecond), atau boleh ditetapkan kepada 0 untuk menghalang, terus memantau sehingga ada mesej yang dikembalikan.

Sudah tentu, selain komunikasi antara benang paralel dan benang utama, komunikasi antara benang paralel juga boleh dilakukan secara langsung.

Dapatkan ID benang semasa dalam fungsi pelaksanaan benang yang disatukan

Dalam contoh di atas, ia digunakan.var id = __threadId()__threadId()Fungsi boleh mendapatkan ID untuk thread semasa.

Variabel yang disimpan di antara benang yang dikongsi

Selain komunikasi antara benang, interaksi boleh dilakukan dengan menggunakan pembolehubah bersama.

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的值
}

Ini adalah demonstrasi ringkas semua fungsi.


Berkaitan

Lebih lanjut

Pisau tulangMenerbitkan cetakan ini: Error ReferenceError: '__Thread' is not defined at main (__FILE__:5)

Pisau tulangMengumpul dan Belajar

Pencipta KuantitiPenguatkuasa Peningkatan