簡體   English   中英

是否可以終止正在運行的Web工作者?

[英]Is it possible to terminate a running web worker?

我有一個Web工作者使用ajax-requests運行耗時的例程任務。 我可以從主線程中終止它們而不是等待它們完成嗎?

這就是我產生和終止它的方式:

$("button.parse-categories").click(function() {
    if (parseCategoriesActive==false) {
        parseCategoriesActive = true;
        parseCategoriesWorker = new Worker("parseCategories.js");


        $("button.parse-categories-cancel").click(function() {
            parseCategoriesWorker.terminate();
            parseCategoriesActive = false;
        });             
    }
});

這是工人代碼:

function myAjax(url, async, callback) {
    xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
            callback(xmlhttp.responseText);
        if (xmlhttp.readyState==4 && xmlhttp.status!=200) {
            self.postMessage("error");
            throw "error in ajax: "+xmlhttp.status;
        }
    }
    xmlhttp.open("GET", url, async);
    xmlhttp.send();
}

var parseCategoriesActive = true;
var counter = 0;
do {
    myAjax('parser.php', false, function(resp) {
        if (resp=='success')
            parseCategoriesActive = false;
        else {
            counter += Number(resp);
            self.postMessage(counter);
        }       
    });
} while (parseCategoriesActive==true);

你可以使用terminate()殺死任何webworker。

引用MDN

Worker.terminate()方法立即終止Worker。 這並不能為工人提供完成業務的機會; 它只是立即停止。

我做了這個簡單的腳本,似乎FF和Chrome的問題仍然存在:

    var myWorker = new Worker("w.js");

    myWorker.onmessage = function(e) {
        console.log('Message received from worker:'+e.data);
    }
    myWorker.postMessage(100);
    setTimeout(stopWW, 500) ;

    function stopWW(){
        console.log('TERMINATE');
        myWorker.terminate();
    }

而網絡工作者是:

    onmessage = function(e) {
      var n = e.data;
      console.log('Message received from main script:'+n);
      for (var i=0;i<n;i++){
        console.log('i='+i);
         postMessage(i);
      } 
    }

一旦主線程終止webworker所以它不再接收postmessage但是webworker仍然在場景下運行,這是一個輸出:

"Message received from main script:100" w.js:3:2
"i=0" w.js:5:1
"Message received from worker:0" w.html:6:2
"i=1" w.js:5:1
...
"Message received from worker:21" w.html:6:2
"i=22" w.js:5:1
"TERMINATE" w.html:13:1
"i=23" w.js:5:1
"i=24" w.js:5:1
...
"i=99" w.js:5:1

OP清楚地問:

我可以從主線程中終止它們而不是等待它們完成嗎?

他並沒有問工人應該如何優雅地退出內部。 他想從外部線程中非常不合理地殺死任何工人。

  • 假設worker實例在上下文范圍內,您可以通過調用其terminate()函數來terminate() 任何 Web worker。

網絡工作者也有一個生命周期 他們將在特定條件下自行終止。

  • 您可以通過關閉創建它的頁面/框架來終止專用工作程序。 這就是專用的意思 - 它只允許服務一個頁面。 關閉頁面會調用專用工作程序的自終止序列。

  • 您可以通過關閉創建它的域的所有頁面來終止共享工作者。 這就是共享的意思 - 它允許從域中提供多個頁面。 關閉所有域頁會調用共享工作程序的自終止序列。

  • 通過關閉所有域頁面也可以殺死其他工作者類型。

這是一個終止一些不受歡迎的工作機器人竊取你的CPU的例子:

 // Create worker bots that consume CPU threads var Blob = window.Blob; var URL = window.webkitURL || window.URL; var numbots = 4; var bots = []; var bot = "while(true){}"; bot = new Blob([bot], { type: 'text/javascript' }); bot = URL.createObjectURL(bot); // Intruders ... for (var i=0; i<numbots; i++) bots[i] = new Worker(bot); document.getElementById("alert").play(); // Hasta la vista ... function terminator(){ if (bots){ for (worker in bots) bots[worker].terminate(); document.getElementById("terminator").play(); bots = null; } } 
 <img src="https://i.imgur.com/BHsjSzj.jpg" width="100%" onclick="terminator()"> <audio id="terminator" src="http://dcerisano.github.io/assets/audio/hastalavista.mp3"> <audio id="alert" src="http://dcerisano.github.io/assets/audio/alert.mp3"> 

  • 使用CPU監視器確認代碼段正在運行。
  • 按按鈕終止工人機器人。
  • “隱藏結果”將關閉代碼段頁面/框架,也會終止工作程序機器人。

希望這個答案對那些希望構建應用程序的人有用,這些應用程序可以搜尋和殺死作為網絡工作者實施的不受歡迎的僵屍程序(例如,竊取你的電力,帶寬並使你成為龐氏的附件的機器人

例如, 此Chrome擴展程序可檢測並有選擇地阻止網絡工作人員(各種機器人,包括礦工)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM