Membuat program kebijakan benar-benar berjalan secara paralel, menambahkan dukungan multi-threaded pada dasar sistem untuk kebijakan JavaScript

Penulis:Mimpi kecil, Dibuat: 2023-03-02 14:19:15, Diperbarui: 2024-03-20 15:06:41

img

Membuat program kebijakan benar-benar berjalan secara paralel, menambahkan dukungan multi-threaded pada dasar sistem untuk kebijakan JavaScript

Ketika menggunakan bahasa JavaScript untuk mengembangkan kebijakan di FMZ, karena arsitektur kebijakan adalah konsultatif.exchange.GoFungsi untuk melakukan panggilan serentak beberapa antarmuka, sehingga memenuhi kebutuhan beberapa skenario serentak. Namun jika ingin benar-benar membuat sebuah thread secara terpisah untuk melakukan serangkaian operasi tidak mungkin, seperti bahasa Python, menggunakanthreadingSaya ingin membuat beberapa desain paralel.

Berdasarkan kebutuhan ini, FMZ platform meng-upgrade dasar-dasar sistem; juga menambahkan dukungan multi-threaded yang sebenarnya untuk bahasa JavaScript; fitur-fitur rinci termasuk:

  • Menciptakan thread secara bersamaan untuk menjalankan fungsi kustom.
  • Komunikasi antar benang.
  • Variabel yang disimpan di antara thread yang dibagikan.
  • Tunggu hingga thread selesai dan mengembalikan hasil pelaksanaannya.
  • "Kami tidak bisa mengakhiri hubungan kami dengan orang-orang yang tidak bertanggung jawab", katanya.
  • Mendapatkan ID thread saat ini dalam fungsi pelaksanaan thread paralel.

Di bawah ini, kita akan membagikan informasi tentang masing-masing fitur.

Membuat fungsi khusus yang dijalankan pada waktu bersamaan

__ThreadFungsi dapat membuat sebuah thread dan menjalankan sebuah fungsi secara bersamaan. Misalnya, perlu membuat sebuah fungsi secara bersamaan.func1func1Apa yang dilakukan fungsi ini? Kita bisa membuatnya ditambahkan dari 0 ke 9, dan untuk melihat proses penjumlahan ini secara bertahap, kita menggunakan for loop dalam fungsi func1 untuk menghentikan setiap kali (fungsi Sleep digunakan untuk tidur beberapa milidetik) waktu 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 skenario aplikasi praktis, kita dapat melakukan permintaan HTTP secara bersamaan 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 thread untuk mengeksekusi sumber daya pemulihan dan mengembalikan hasil eksekusi

Jadi kita akan menggunakan fungsi ini untuk pertama kalinya dalam fungsi utama.__threadJoinFungsi untuk menunggu string paralel selesai, variabelretMenerima__threadJoinNilai balik dari fungsi, kita mencetak nilai balik ini, dan kita dapat melihat hasil spesifik dari pelaksanaan string paralel ini.

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

Pemberhentian paksa dan daur ulang sumber daya

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 contoh yang baru saja saya berikan, setelah membuat thread, Anda dapat memaksa terminasi thread setelah menunggu 1 detik.

Komunikasi antar benang

Komunikasi antar benang terutama digunakan__threadPostMessageFungsi dan__threadPeekMessageFungsi. Mari kita lihat contoh sederhana 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 mengirim pesan ke suatu thread, parameter pertama adalah ID yang dikirim ke thread tertentu, parameter kedua adalah pesan yang dikirim, yang dapat berupa string, nilai, array, objek JSON, dll. Fungsi dapat mengirim pesan ke thread utama dalam fungsi thread paralel, ID yang didefinisikan sebagai 0 untuk thread utama.

__threadPeekMessageFungsi ini digunakan untuk mendengarkan pesan yang dikirimkan oleh suatu thread, dapat mengatur waktu laten (millisecond) atau dapat diatur menjadi 0 untuk memblokir, terus mendengarkan sampai ada pesan yang dikembalikan.

Tentu saja, selain komunikasi antara thread paralel dan thread utama, komunikasi antara thread paralel juga dapat dilakukan secara langsung.

Mendapatkan ID thread saat ini dalam fungsi pelaksanaan thread paralel

Dalam contoh di atas, kita menggunakanvar id = __threadId()__threadId()Fungsi dapat mendapatkan ID dari thread saat ini.

Variabel yang disimpan di antaranya

Selain komunikasi antar-threaded, interaksi dapat dilakukan dengan menggunakan variabel 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 singkat dari semua fiturnya.


Berkaitan

Lebih banyak

Pisau tulangReferenceError: '__Thread' is not defined at main (__FILE__:5)

Pisau tulangKoleksi Belajar

Penemu KuantitasUpgrade Trustee