Node.jsÉó¤Êý¾ÝÃܼ¯ÐÍʵʱ£¨data-intensive
real-time£©½»»¥µÄÓ¦Óó¡¾°¡£È»¶øÊý¾ÝÃܼ¯ÐÍʵʱӦÓóÌÐò²¢²»ÊÇÖ»ÓÐI/OÃܼ¯ÐÍÈÎÎñ£¬µ±Åöµ½CPUÃܼ¯ÐÍÈÎÎñʱ£¬±ÈÈçÒª¶ÔÊý¾Ý¼Ó½âÃÜ£¨node.bcrypt.js£©£¬Êý¾ÝѹËõºÍ½âѹ£¨node-tar£©£¬»òÕßÒª¸ù¾ÝÓû§µÄÉí·Ý¶ÔͼƬ×öЩ¸öÐÔ»¯´¦Àí£¬ÔÚÕâЩ³¡¾°Ï£¬Ö÷Ïß³ÌÖÂÁ¦ÓÚ×ö¸´ÔÓµÄCPU¼ÆË㣬I/OÇëÇó¶ÓÁÐÖеÄÈÎÎñ¾Í±»×èÈû¡£
Node.jsÖ÷Ï̵߳Äevent loopÔÚ´¦ÀíËùÓеÄÈÎÎñ/ʼþʱ£¬¶¼ÊÇÑØ×Åʼþ¶ÓÁÐ˳ÐòÖ´Ðеģ¬ËùÒÔÔÚÆäÖÐÈκÎÒ»¸öÈÎÎñ/ʼþ±¾ÉíûÓÐÍê³É֮ǰ£¬ÆäËüµÄ»Øµ÷¡¢¼àÌýÆ÷¡¢³¬Ê±¡¢nextTick()µÄº¯Êý¶¼µÃ²»µ½ÔËÐеĻú»á£¬ÒòΪ±»×èÈûµÄevent
loop¸ù±¾Ã»»ú»á´¦ÀíËüÃÇ£¬´Ëʱ³ÌÐò×îºÃµÄÇé¿öÊDZäÂý£¬×îÔãµÄÇé¿öÊÇÍ£ÖͲ»¶¯£¬ÏñËÀµôÒ»Ñù¡£
Ò»¸ö¿ÉÐеĽâ¾ö·½°¸ÊÇпª½ø³Ì£¬Í¨¹ýIPCͨÐÅ£¬½«CPUÃܼ¯ÐÍÈÎÎñ½»¸ø×Ó½ø³Ì£¬×Ó½ø³Ì¼ÆËãÍê±Ïºó£¬ÔÙͨ¹ýipcÏûϢ֪ͨÖ÷½ø³Ì£¬²¢½«½á¹û·µ»Ø¸øÖ÷½ø³Ì¡£
ºÍ´´½¨Ïß³ÌÏà±È£¬¿ª±Ùнø³ÌµÄϵͳ×ÊÔ´Õ¼ÓÃÂʴ󣬽ø³Ì¼äͨÐÅЧÂÊÒ²²»¸ß¡£Èç¹ûÄܲ»¿ªÐ½ø³Ì¶øÊÇпªỊ̈߳¬½«CPUºÄʱÈÎÎñ½»¸øÒ»¸ö¹¤×÷Ïß³ÌÈ¥×ö£¬È»ºóÖ÷Ïß³ÌÁ¢¼´·µ»Ø£¬´¦ÀíÆäËûµÄI/OÇëÇ󣬵ȵ½¹¤×÷Ï̼߳ÆËãÍê±Ïºó£¬Í¨ÖªÖ÷Ï̲߳¢½«½á¹û·µ»Ø¸øÖ÷Ï̡߳£ÄÇôÔÚÍ¬Ê±Ãæ¶ÔI/OÃܼ¯ÐͺÍCPUÃܼ¯ÐÍ·þÎñµÄ³¡¾°Ï£¬NodeµÄÖ÷Ïß³ÌÒ²»á±äµÃÇáËÉ£¬²¢ÄÜʱ¿Ì±£³Ö¸ßÏìÓ¦¶È¡£
Òò´Ë£¬ºÍ¿ª½ø³ÌÏà±È£¬Ò»¸ö¸ü¼ÓÓÅÐãµÄ½â¾ö·½°¸ÊÇ£º
1.²»¿ª½ø³Ì£¬¶øÊǽ«CPUºÄʱ²Ù×÷½»¸ø½ø³ÌÄÚµÄÒ»¸ö¹¤×÷Ïß³ÌÍê³É¡£
2.CPUºÄʱ²Ù×÷µÄ¾ßÌåÂß¼Ö§³Öͨ¹ýC++ºÍJSʵÏÖ¡£
3.JSʹÓÃÕâ¸ö»úÖÆÓëʹÓÃI/O¿âÀàËÆ£¬·½±ã¸ßЧ¡£
4.ÔÚÐÂÏß³ÌÖÐÔËÐÐÒ»¸ö¶ÀÁ¢µÄV8 VM£¬ÓëÖ÷Ï̵߳ÄVM²¢·¢Ö´ÐУ¬²¢ÇÒÕâ¸öÏ̱߳ØÐëÓÉÎÒÃÇ×Ô¼ºÍйܡ£
ΪÁËʵÏÖÒÔÉÏËĸöÄ¿±ê£¬ÎÒÃÇÔÚNodeÖÐÔö¼ÓÁËÒ»¸öbackgroundthreadỊ̈߳¬ÎÄÕÂÉÔºò»áÏêϸ½âÊÍÕâ¸ö¸ÅÄî¡£ÔÚ¾ßÌåʵÏÖÉÏ£¬ÎªNodeÔö¼ÓÁËÒ»¸öpt_cµÄÄÚ½¨C++Ä£¿é¡£Õâ¸öÄ£¿é¸ºÔð°ÑCPUºÄʱ²Ù×÷·â×°³ÉÒ»¸öTask£¬Å׸øbackgroundthread£¬È»ºóÁ¢¼´·µ»Ø¡£¾ßÌåµÄÂß¼ÔÚÁíÒ»¸öÏß³ÌÖд¦Àí£¬Íê³ÉÖ®ºó£¬É趨½á¹û£¬Í¨ÖªÖ÷Ï̡߳£Õâ¸ö¹ý³Ì·Ç³£ÀàËÆÓÚÒì²½I/OÇëÇó¡£
¾ßÌåÂß¼ÈçÏÂͼ£º

NodeÌṩÁËÒ»ÖÖ»úÖÆ¿ÉÒÔ½«CPUºÄʱ²Ù×÷½»¸øÆäËûÏß³ÌÈ¥×ö£¬µÈµ½Ö´ÐÐÍê±ÏºóÉèÖýá¹û֪ͨÖ÷Ïß³ÌÖ´ÐÐcallbackº¯Êý¡£ÒÔÏÂÊÇÒ»¶Î´úÂ룬ÓÃÀ´ÑÝʾÕâ¸ö¹ý³Ì£º
int main() { loop = uv_default_loop(); int data[FIB_UNTIL]; uv_work_t req[FIB_UNTIL]; int i; for (i = 0; i < FIB_UNTIL; i++) { data[i] = i; req[i].data = (void *) &data[i]; uv_queue_work(loop, &req[i], fib, after_fib); } return uv_run(loop, UV_RUN_DEFAULT); } |
ÆäÖк¯Êýuv_queue_workµÄ¶¨ÒåÈçÏ£º
UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb); |
²ÎÊýwork_cbÊÇÔÚÁíÍâÏß³ÌÖ´Ðеĺ¯ÊýÖ¸Õ룬after_work_cbÏ൱ÓÚ¸øÖ÷Ïß³ÌÖ´ÐеĻص÷º¯Êý¡£
ÔÚwindowsƽ̨ÉÏ£¬uv_queue_work×îÖÕµ÷ÓÃAPIº¯ÊýQueueUserWorkItemÀ´ÅÉ·¢Õâ¸ötask£¬×îÖÕÖ´ÐÐtask
µÄÏß³ÌÊÇÓɲÙ×÷ϵͳÍйܵģ¬Ã¿´Î¿ÉÄܶ¼²»Ò»Ñù¡£Õâ²»Âú×ãÉÏÊöµÚËÄÌõ¡£
ÒòΪÎÒÃÇÒªÖ§³ÖÔÚÏß³ÌÖÐÔËÐÐjs´úÂ룬Õâ¾ÍÐèÒª¿ªÒ»¸öV8 VM£¬ËùÒÔÐèÒª°ÑÕâ¸öÏ̶̹߳¨ÏÂÀ´£¬Ìض¨ÈÎÎñ£¬Ö»½»¸øÕâ¸öÏ̴߳¦Àí¡£²¢ÇÒÒ»µ©´´½¨£¬²»¹ÜÓÐûÓÐtask£¬¶¼²»ÄÜËæ±ãÍ˳ö¡£Õâ¾ÍÐèÒªÎÒÃÇ×Ô¼ºÎ¬»¤Ò»¸öÏ̶߳ÔÏ󣬲¢ÇÒÌṩ½Ó¿Ú£¬Ê¹µÃʹÓÃÕß¿ÉÒÔ·½±ãµÄÉú³ÉÒ»¸ö¶ÔÏó²¢ÇÒÌá½»¸øÕâ¸öÏ̵߳ÄÈÎÎñ¶ÓÁС£
ÔÚ°ó¶¨ÄÚ½¨Ä£¿épt_cµÄʱºò£¬»á´´½¨Ò»¸öbackground threadµÄÏ̶߳ÔÏó¡£Õâ¸öÏß³ÌÓµÓÐÒ»¸ötaskloop£¬ÓÐÈÎÎñ¾Í´¦Àí£¬Ã»ÓÐÈÎÎñ¾ÍµÈ´ýÔÚÒ»¸öÐźÅÁ¿ÉÏ¡£¶àÏß³ÌÒª¿¼ÂÇÏ̼߳äͬ²½µÄÎÊÌâ¡£Ïß³Ìͬ²½Ö»·¢ÉúÔÚ¶Áд´ËÏ̵߳Äincomming
queue µÄʱºò¡£NodeµÄÖ÷Ïß³ÌÉú³Étaskºó£¬Ìá½»µ½Õâ¸öÏ̵߳Äincomming queueÖУ¬²¢¼¤»îÐźÅÁ¿È»ºóÁ¢¼´·µ»Ø¡£ÔÚÏÂÒ»´ÎÑ»·ÖУ¬backgroundthread´Óincomming
queueÖÐÈ¡³öËùÓеÄtask£¬·ÅÈëworking queue£¬È»ºóÒÀ´ÎÖ´ÐÐworking queueÖеÄtask¡£Ö÷Ï̲߳»·ÃÎÊworking
queueÒò´Ë²»ÐèÒª¼ÓËø¡£ÕâÑù×ö¿ÉÒÔ½µµÍ³åÍ»¡£
Õâ¸öÏß³ÌÔÚ½øÈëtaskloopÑ»·Ö®Ç°»á½¨Á¢Ò»¸ö¶ÀÁ¢µÄV8 VM£¬×¨ÃÅÓÃÀ´Ö´ÐÐbackgroundjsµÄ´úÂë¡£Ö÷Ï̵߳Äv8ÒýÇæºÍÕâ¸öÏ̵߳ĿÉÒÔ²¢ÐÐÖ´ÐС£ËüµÄÉúÃüÖÜÆÚÓëNode½ø³ÌµÄÉúÃüÖÜÆÚÒ»Ö¡£
// pt_cÄ£¿éµÄ³õʼ»¯´úÂë
void Init(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context,
void* priv) {
//Create working thread, focus on cup intensive
task
if(!CWorkingThread::GetInstance().Start()){
return;
}
Environment* env = Environment::GetCurrent(context);
// load dll, Including all the cpu-intensive functions
NODE_SET_METHOD(target, "registermodule",
RegisterModule);
NODE_SET_METHOD(target, "posttask",
PostTask);
// post a task that run a cpu-intensive function
defined in backgroundjs
NODE_SET_METHOD(target, "jstask", JsTask);
} |
¿ÉÒÔ°ÑËùÓÐCPUºÄʱÂß¼·ÅÈëbackgroundJsÖУ¬Ö÷Ïß³Ìͨ¹ýÉú³ÉÒ»¸ötask£¬Ö¸¶¨ºÃÔËÐеĺ¯ÊýºÍ²ÎÊý£¬Å׸ø¹¤×÷Ï̡߳£¹¤×÷Ïß³ÌÔÚÖ´ÐÐtaskµÄ¹ý³ÌÖе÷ÓÃÔÚbackgroundJsÖеĺ¯Êý¡£BackgroundJsÊÇÒ»¸ö.jsÎļþ£¬ÔÚÀïÃæÌí¼ÓCPUºÄʱº¯Êý¡£
background.js´úÂëʾÀý£º
var globalFunction = function(v){ var obj; try { obj = JSON.parse(v); ¡¡} catch(e) { return e; }
¡¡var a = obj.param1;
¡¡var b = obj.param2;
¡¡var i;
¡¡// simulate CPU intensive process...
¡¡for(i = 0; i < 95550000; ++i) {
¡¡¡¡ i += 100;
i -= 100;
¡¡}
return (a + b).toString();
} |
ÔËÐÐNode£¬ÔÚ¿ØÖÆÌ¨ÊäÈ룺
var bind = process.binding('pt_c'); var obj = {param1: 123,param2: 456}; bind.jstask('globalFunction', JSON.stringify(obj), function (err, data) { if (err) { console.log("err"); } else { console.log(data); } }); |
µ÷Óõķ½·¨ÊÇbind.jstask£¬ÉÔºó»á½âÊÍÕâ¸öº¯ÊýµÄÓ÷¨¡£
ÒÔÏÂÊDzâÊÔ½á¹û£º

ÉÏÃæÕâ¸öʵÑé²Ù×÷²½ÖèÈçÏ£º
1.Ê×ÏȰó¶¨pt_cÄÚ½¨Ä£¿é¡£°ó¶¨µÄ¹ý³Ì»áµ÷ÓÃÄ£¿é³õʼ»¯º¯Êý£¬ÔÚÕâ¸öº¯ÊýÖУ¬´´½¨ÐÂÏ̡߳£
2.¿ìËÙ¶à´Îµ÷ÓÃbackgroundjsÖеÄCPUºÄʱº¯Êý£¬ÉÏÃæµÄʵÑéÖÐÁ¬Ðøµ÷ÓÃÁËÈý´Î¡£
µ±backgroundjsÖеĺ¯ÊýÍê³Éºó£¬Ö÷Ï߳̽ӵ½Í¨Öª,ÔÚÐÂÒ»ÂÖµÄevenloopÖУ¬µ÷Óûص÷º¯Êý£¬´òÓ¡³ö½á¹û¡£Õâ¸öʵÑé˵Ã÷ÁËCPUºÄʱ²Ù×÷Òì²½Ö´ÐС£
·½·¨jstask×ܹ²Èý¸ö²ÎÊý£¬Ç°Á½¸ö²ÎÊýΪ×Ö·û´®£¬·Ö±ðÊÇbackground.jsÖеÄÈ«¾Öº¯ÊýÃû³Æ£¬´«¸øº¯ÊýµÄ²ÎÊý¡£×îºóÒ»¸ö²ÎÊýÊÇÒ»¸öcallbackº¯Êý£¬Òì²½Áô¸øÖ÷Ïß³ÌÔËÐС£
ΪʲôÓÃ×Ö·û´®×ö²ÎÊý£¿
ΪÁËÊÊÓ¦¸÷ÖÖ²»Í¬µÄ²ÎÊýÀàÐÍ£¬¾ÍÐèҪΪC++º¯ÊýÌṩ¸÷ÖÖ²»Í¬µÄº¯ÊýʵÏÖ£¬ÕâÊǷdz£ÊÜÏÞÖÆµÄ¡£C++¸ù¾Ýº¯ÊýÃû»ñÈ¡backgroundjsÖеĺ¯ÊýÈ»ºó½«²ÎÊý´«µÝ¸øjs¡£ÔÚjsÖУ¬´¦Àíjson×Ö·û´®ÊǷdz£ÈÝÒ׵ģ¬Òò´Ë²ÉÓÃ×Ö·û´®£¬¼ò»¯ÁËC++µÄÂß¼£¬jsÓÖÄܹ»·½±ãµÄÉú³ÉºÍ½âÎö²ÎÊý¡£Í¬ÑùµÄÀíÓÉ£¬backgroundjsÖк¯ÊýµÄ·µ»ØÖµÒ²Îªjson´®¡£
¶ÔC++µÄÖ§³Ö
ÔÚ¿ÁÇóÐÔÄܵij¡¾°£¬pt_cÔÊÐí¼ÓÔØÒ»¸ö.dllÎļþµ½node½ø³Ì£¬Õâ¸ödllÎļþ°üº¬CPUºÄʱ²Ù×÷¡£js¼ÓÔØpt_cµÄʱºò£¬Ö¸¶¨ÎļþÃû¼´¿ÉÍê³É¼ÓÔØ¡£
´úÂëʾÀý£º
var bind = process.binding('pt_c'); bind.registermodule('node_pt_c.dll', 'DllInit', 'Json to Init'); bind.posttask('Func_example', 'Json_Param', function (err, data) { if (err) { console.log("err"); } else { console.log(data); } }); |
ÓëbackgroundjsÏà±È£¬¼ÓÔØC++Ä£¿é¶àÁËÒ»¸ö²½Ö裬Õâ¸ö²½ÖèÊǵ÷ÓÃbind.registermodule¡£Õâ¸öº¯Êý¸ºÔ𽫼ÓÔØdll²¢¸ºÔð¶ÔÆä³õʼ»¯¡£Ò»µ©³É¹¦ºó£¬²»ÄÜÔÙ¼ÓÔØÆäËûÄ£¿é¡£ËùÓеÄCPUºÄʱ²Ù×÷º¯Êý¶¼Ó¦¸ÃÔÚÕâ¸ödllÎļþÖÐʵÏÖ¡£
×ܽá
ÕâÆªÎÄÕÂÌá³öÁËbackgroundjsÕâ¸öеĸÅÄÀ©Õ¹ÁËNode.jsµÄÄÜÁ¦,½â¾öÁËNodeÔÚ´¦ÀíCPUÃܼ¯ÈÎÎñʱµÄ¶Ì°å¡£Õâ¸ö½â¾ö·½°¸Ê¹µÃʹÓÃNodeµÄ¿ª·¢ÈËÔ±Ö»ÐèÒª¹Ø×¢backgroundjsÖеĺ¯Êý¡£±ÈÆð¶à¿ª½ø³Ì»òÕßÐÂÌí¼ÓÄ£¿éµÄ½â¾ö·½°¸¸ü¸ßЧ£¬Í¨ÓúÍÒ»Ö¡£ÎÒÃǵĴúÂëÒѾ¿ªÔ´£¬Äú¿ÉÒÔÔÚhttps://github.com/classfellow/node/tree/Ansy-CPU-intensive-work--in-one-processÏÂÔØ¡£
Ö§³ÖbackgroundjsÒ»¸öÎȶ¨Node°æ±¾Äú¿ÉÒÔÔÚhttp://www.witch91.com/nodejs.rarÏÂÔØ¡£ |