《西虹市首富 》百度网盘高清资源免费在线观看;
链接: https://pan.baidu.com/s/1KWNQNwxRRCLH4Lu2TfhNUQ
提取码:h3ph复制这段内容后打开百度网盘手机App,操作更方便哦
作品简介:
该片讲述了混迹于丙级业余足球队的守门员王多鱼,因比赛失利被开除离队,却因继承二爷遗产而获得大笔财富,由此引发一系列令人哭笑不得的事件。
Fibers 又称纤程,可以理解为协同程序,类似py和lua都有这样的模型。使用Fibers可以避免对资源的互抢,减少cpu和内存的消耗,但是Fibers并不能够真正的并行执行,同一时刻只有一个Fibers在执行,如果在其中一个Fibers中执行过多的cpu操作或者写了个死循环,则整个主程序将卡死住。node中的异步事件循环模型就有点象这个。Threads 又称线程,他可以在同一时刻并行的执行,他们共享主进程的内存,在其中某一时刻某一个threads锁死了,是不会影响主线程以及其他线程的执行。但是为了实现这个模型,我们不得不消耗更多的内存和cpu为线程切换的开销,同时也存在可能多个线程对同一内存单元进行读写而造成程序崩溃的问题。
很多让node支持多线程的方法是使用c/c++的addon来实现,在需要进行cpu密集型计算的地方,把js代码改写成c/c++代码,但是如果开发人员对c++不是很熟悉,一来开发效率会降低不少,二来也容易出bug,而且我们知道在addon中的c++代码除了编译出错外,是很难调试的,毕竟没有vs调试c++代码方便。
令人振奋的消息,我们为什么不让node也支持多线程模型呢?于是Jorge为我们开发出了一个让node支持多线程模型的模块:threads_a_gogo
github地址:https://github.com/xk/node-threads-a-gogo
有了threads-a-gogo(以下简称TAGG)这个模块之后,我们可以让node做更多的事情,我记得以前我看过一篇文章,说node只能应付i/o密集型场景,在cpu密集型场景将完败给apache,因为apache是为每一个请求起一条线程的,所以在处理cpu密集型任务时一个线程的高强度计算不会很大程度的影响其他线程,类似的还有php的fastcgi,这也是很多拿node和php进行比较时,php的拥护者们一直提出的理论。
我们先来做一个简单的测试,用我们suqian大大最喜欢的斐波那契数组来看一下,加入了多线程的node有多么的强悍:(测试机器为4CPU)
没有使用TAGG的正常情况,异步也帮不了我们应对cpu密集型任务
function fibo (n) {
return n >1 ? fibo(n - 1) + fibo(n - 2) : 1
}
var n=8
function back(){
if(!--n) return console.timeEnd('no thread')
}
console.time('no thread')
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
process.nextTick(function(){
console.log(fibo (40))
back()
})
我们模拟了8个异步的行为,测试用的node v0.8.16版本,所以 process.nextTick还是异步方法。最后我们输出结果为:
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
no thread: 23346ms
接下来我们使用TAGG模块来测试同样的执行8次斐波那契数组计算,看看成绩如何?
function fibo (n) {
return n >1 ? fibo(n - 1) + fibo(n - 2) : 1
}
console.time('8 thread')
var numThreads= 8//创建线程池,最大数为8
var threadPool= require('threads_a_gogo').createPool(numThreads).all.eval(fibo)//为线程池注册程序
var i=8
var cb = function(err,data){ //注册线程执行完毕的回调函数
console.log(data)
if(!--i){
threadPool.destroy()
console.timeEnd('8 thread')
}
}
threadPool.any.eval('fibo(40)', cb)//开始向线程池中执行fibo(40)这个任务
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
threadPool.any.eval('fibo(40)', cb)
最重的结果:
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
8 thread: 9510ms
相比不使用多线程模型的node,使用了TAGG模块之后,我们在4CPU服务器上的测试结果要快上一倍还不止。
到这里我们看上去找到了一个比较完美的解决方案应对CPU密集型任务,但是可能有同学会说,我可以使用cluster来做相同的事情,下面我们来做一个使用cluster计算这些任务的情况:
var cluster = require('cluster')
var numCPUs = 8
function fibo (n) {
return n >1 ? fibo(n - 1) + fibo(n - 2) : 1
}
console.time('8 cluster')
if (cluster.isMaster) {
// Fork workers.
for (var i = 0i <numCPUsi++) {
cluster.fork()
}
var i = 8
cluster.on('exit', function(worker, code, signal) {
if(!--i){
console.timeEnd('8 cluster')
process.exit(0)
}
})
} else {
console.log(fibo (40))
process.exit(0)
}
代码上的复杂程度比使用TAGG要高的多,而且如果是动态计算斐波那契数组的结果,编码将更加困难,需要在fork时挂上不同的参数,出错的几率也更大。同时还有更重要的一个事情,如果是创建一个http服务器,如果4个cluster都在计算fibo,那第5个请求node将无法处理,而是用TAGG则还是能够正常处理的,所以cluster并不能解决单线程模型的cpu密集计算带来的阻塞问题,我们看下测试结果:
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
8 cluster: 11925ms
TAGG模块还有其他更多的功能,比如事件触发,平滑退出,查看线程工作状态等等,总之TAGG模块给node注入了新的活力,让node一直饱受诟病的处理cpu密集任务问题得到了一个妥善的解决,就算你不擅长c++代码,也能够轻松编写出多线程的真正的非阻塞node程序了。
FileUpload 是国外一个纯javascript 写的大文件上传组件,该组件支持分片上传,断点续传,多文件等功能。 下面就为大家分享FileUpload上传组件自定义模板(FineUploaderBasic)的使用方法: 以下是配置代码: 前端配置: <!--定义按钮--> <div id="basic_uploader_fine"><i class="icon-upload icon-white"></i>选择文件</div> <div id="triggerUpload">点击上传</div> <!--显示信息--> <div id="messages"></div> <div id="cancelUpload" class="buttons">取消</div> <div id="cancelAll" class="buttons">取消全部</div> <div id="pauseUpload" class="buttons">暂停上传</div> <div id="continueUpload" class="buttons">继续上传</div> <script> $(document)/community/01ff2756629d096ac725b2c8e95102/community/01ff2756629d096ac725b2c8e95102.gif" width="50px" height="50px" alt="Saving. Please hold.">' + '上传文件中...... ')}},//上传完成后onComplete: function(id, fileName, responseJSON) { if (responseJSON.success) { var img = responseJSON['target'] $('#file-' + id).removeClass('alert-info') .addClass('alert-success') .html('<i class="icon-ok"></i>' + '上传成功! ' + '“' + fileName + '”' )} else { $('#file-' + id).removeClass('alert-info') .addClass('alert-error') .html('<i class="icon-exclamation-sign"></i>' + 'Error with ' + '“' + fileName + '”: ' + responseJSON.error)}},onError: function(id, name, reason, maybeXhrOrXdr) { console.log(id + '_' + name + '_' + reason) }, } })//手动触发上传上传$('#triggerUpload').click(function() {uploader.uploadStoredFiles() }) //取消某一个上传$('#cancelUpload').click(function() {uploader.cancel(0) }) //取消所有未上传的文件$('#cancelAll').click(function() { //单个文件上传没有作用 因为已经在上传的不能使用这个cancelAll取消上传 uploader.cancelAll() }) //暂停上传某个文件 $('#pauseUpload').click(function() { uploader.pauseUpload(0) }) // 继续上传 $('#continueUpload').click(function() { uploader.continueUpload(0) }) }) </script> php代码: //handler.php文件官网上下 require_once "handler.php" $uploader = new UploadHandler() // 文件类型限制 $uploader->allowedExtensions = array() // 文件大小限制 $uploader->sizeLimit = null // 上传文件框 $uploader->inputName = "qqfile" // 定义分组文件存放位置 $uploader->chunksFolder = "chunks" $method = $_SERVER["REQUEST_METHOD"] //上传目的文件夹(由于原来的文件存放规则不符合我们的需求所以修改了handler.php的代码添加了个文件夹生成规则【你也可以自定义】) $uploadDirectory = $uploader->getPathName('member_avatar') if ($method == "POST") { header("Content-Type: text/plain")// 分组上传完成后对分组进行合并 if (isset($_GET["done"])) {$result = $uploader->combineChunks($uploadDirectory)// 合并分组文件 } else {//开始上传文件$result = $uploader->handleUpload($uploadDirectory) // 获取上传的名称$result["uploadName"] = $uploader->getUploadName()} echo json_encode($result) } //删除文件处理 else if ($method == "DELETE") { $result = $uploader->handleDelete($uploadDirectory) echo json_encode($result) } else { header("HTTP/1.0 405 Method Not Allowed") }以上是一个简单的自定义模板的配置,希望对大家的学习有所帮助。