nodejs中使⽤多线程编程的⽅法实例
这篇⽂章主要介绍了nodejs中使⽤多线程编程的⽅法实例,本⽂使⽤nodejs addon借助c/c++的能⼒扩展nodejs多线程编程,需要的朋友可以参考下
在nodejs中,我们⽤⼀个从1到4000000的循环来检索质数;c语⾔中,我们设置若⼲个线程,定义count为4000000,每个线程做如下操作要:如果count⼤于0,则取出count的值,并计算是否为质数,同时将count减1。根据这个思路,javascript版本的很容易写:
代码如下:
var count = 0;
for (j = 1; j < 4000000; j++) {
if(zhishu(j)){
count++;
}
}
关键难点就是c语⾔的多线程编程。早期c/c++并没有考虑并⾏计算的需求,所以标准库中并没有提供多线程⽀持。⽽不同的操作系统通常实现也是有区别的。为了避免这种⿇烦,我们采⽤pthread来处理线程。
下载最新版本。由于我对gyp不熟,link依赖lib搞了半天没搞定,最后我的⽅式是,直接把pthread的源代码放到了项⽬⽬录下,并在p中把pthread.c添加到源代码列表中,在编译项⽬的时候把pthread也编译⼀次。修改后的p是这样的:
代码如下:
{
"targets": [
{
"target_name": "hello",
"sources": [ "","pthreads/pthread.c" ],
"include_dirs": [
"<!(node -e \"require('nan')\")",
"pthreads"
],
"libraries": ["Ws2_32.lib"]
}
]
}
当然了,我这种⽅法很⿇烦,如果你们只添加pthread中lib和include⽬录的引⽤,并且不出现依赖问题,那是最好的,就没有必要⽤我的⽅法来做。
那么接下来就进⼊C/C++多线程的⼀切了,定义⼀个线程处理函数:
代码如下:
pthread_mutex_t lock;
num=count--;
pthread_mutex_unlock(&lock);
if(num>0){
if(zhishu(num))x++;
}else{
break;
}
}while(true);
std::cout<<' '<<x<<' ';
pthread_exit(NULL);
return null;
}
在线程与线程之间,对于count这个变量是相互竞争的,我们需要确保同时只能有⼀个线程操作count
变量。我们通过 pthread_mutex_t lock;添加⼀个互斥锁。当执⾏ pthread_mutex_lock(&lock); 时,线程检查lock锁的情况,如果已锁定,则等待、重复检查,阻塞后续代码运⾏;如果锁已释放,则锁定,并执⾏后续代码。相应的, pthread_mutex_unlock(&lock); 就是解除锁状态。
由于编译器在编译的同时,进⾏编译优化,如果⼀个语句没有明确做什么事情,对其他语句的执⾏也没有影响时,会被编译器优化掉。在上⾯的代码中,我加⼊了统计质数数量的代码,如果不加的话,像这样的代码:
代码如下:
for (int j = 0; j < 4000000; j++) {
zhishu(j);
}
是会直接被编译器跳过的,实际不会运⾏。
添加addon的写法已经介绍过了,我们实现从javascript接收⼀个参数,表⽰线程数,然后在c中创建指定数量的线程完成质数检索。完整代码:
代码如下:
#include <nan.h>
#include <math.h>
#include <iostream>
#include "pthreads\pthread.h"
#define MAX_THREAD 100
using namespace v8;
int count=4000000;
pthread_t tid[MAX_THREAD];
pthread_mutex_t lock;
num=count--;
pthread_mutex_unlock(&lock);
if(num>0){
if(zhishu(num))x++;
}else{
break;
}
}while(true);
std::cout<<' '<<x<<' ';
pthread_exit(NULL);
return null;
}
NAN_METHOD(Zhishu){
NanScope();
pthread_mutex_init(&lock,NULL);
double arg0=args[0]->NumberValue();
int c=0;
for (int j = 0; j < arg0 && j<MAX_THREAD; j++) {
pthread_create(&tid[j],NULL,thread_p,NULL);
}
for (int j = 0; j < arg0 && j<MAX_THREAD; j++) {
pthread_join(tid[j],NULL);js脚本编程入门
}
NanReturnUndefined();
}
void Init(Handle<Object> exports){
exports->Set(NanSymbol("zhishu"), FunctionTemplate::New(Zhishu)->GetFunction());
}
NODE_MODULE(hello, Init);
phread_create可以创建线程,默认是joinable的,这个时候⼦线程受制于主线程;phread_join阻塞住主线程,等待⼦线程join,直到⼦线程退出。如果⼦线程已退出,则phread_join不会做任何事。所以对所有的线程都执⾏thread_join,可以保证所有的线程退出后才会例主线程继续进⾏。
完善⼀下nodejs脚本:
代码如下:
var zhishu_c=require('./build/de').zhishu;
function zhishu(num) {
if (num == 1) {
return false;
}
if (num == 2) {
return true;
}
for (var i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
return false;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论