python 多进程 多核_go/node/python 多进程与多核cpu

node

node单线程,没有并发,但是可以利用cluster进行多cpu的利用。cluster是基于child_process的封装,帮你做了创建子进程,负载均衡,IPC的封装。

const cluster = require('cluster');

const http = require('http');

if (cluster.isMaster) {

let numReqs = 0;

setInterval(() => {

console.log(`numReqs = ${numReqs}`);

}, 1000);

function messageHandler(msg) {

if (msg.cmd && msg.cmd === 'notifyRequest') {

numReqs += 1;

}

}

const numCPUs = require('os').cpus().length;

for (let i = 0; i < numCPUs; i++) {

cluster.fork();

}

for (const id in cluster.workers) {

cluster.workers[id].on('message', messageHandler);

}

} else {

// Worker processes have a http server.

http.Server((req, res) => {

res.writeHead(200);

res.end('hello world\n');

process.send({ cmd: 'notifyRequest' });

}).listen(8000);

}

我们通过cluster.fork()来创造几个子进程,让子进程来替我们工作。在fork的时候会传一个参数到子进程,cluster.isMaster就是根据有没有这个参数判断的。

如果是子进程就起一个server。

每个子进程都会绑定到8000端口,这不会引起端口占用吗?

答案是不会,因为listen并不会真的监听到8000端口,它会通过IPC把子进程的消息传到主进程,主进程会创建服务器,然后调用子进程的回调。

在子进程的回调中:子进程会根据主进程是否返回handle句柄来执行下一步的操作,如果没有handle句柄,说明在负载均衡的策略没有选中本进程。那么就自己造一个handle对象返回。

那自己造个对象怎么返回请求呢?

请求到主进程,主进程会分发请求,处理到该请求的子进程会通过IPC与主进程通信,这样就完成了一个请求的响应。

通过cluster完成单机器的负载均衡,那么多机器呢?还是得用nginx。

node & pm2

pm2 是node的进程管理工具,它封装了cluster,可以通过命令行来创建多个进程来处理。

写个config文件:

app.json

{

"name" : "app",

"script" : "src/main.js",

"watch" : true,

"merge_logs" : true,

"instances" : "max", // 使用cluster

"error_file" : "./log/error.log",

"out_file" : "./log/asccess.log",

"pid_file" : "./log/pid.pid",

"cwd" : "./",

"max_restarts" : 10,

"min_uptime": "10s",

"env": {

"NODE_ENV": "development",

"BABEL_ENV": "node"

},

"env_prod" : {

"NODE_ENV": "production"

}

}

pm2 start app.json

也可以不写配置文件直接写pm2 start -i 4 --name server index.js

开启4个instance。

通过参数开启多个子进程,而不需要修改我们的业务代码。

go

go也是非阻塞io,Golang默认所有的任务都在一个cpu核里,如果想使用多核来跑goroutine的任务,需要配置runtime.GOMAXPROCS。

自从Go 1.5开始, Go的GOMAXPROCS默认值已经设置为 CPU的核数,我们不用手动设置这个参数。

我们先说说go的并发。

go本身就可以通过go关键字来进行并发操作。go关键字创建的并发单元在go中叫goroutine。

比如:

package main

import (

"fmt"

"time",

// "runtime"

)

func main() {

go func(){

fmt.Println("123")

}()

go func(){

fmt.Println("456")

}()

// runtime.Gosched()

fmt.Println("789")

time.Sleep(time.Second)

}

会打印789 ,123,456,或者 780,456,123。

在主线程开始就通过go字段开启了2个goroutine,两个goroutine的执行顺序不确定。

如果当前goroutine发生阻塞,它就会让出CPU给其他goroutine。

如果当前goroutine不发生阻塞,一直在执行,那么什么时候执行其他goroutine就看go调度器的处理了。

不过go提供runtime.Gosched()来达到让出CPU资源效果的函数,当然不是不执行,会在之后的某个时间段执行。如果把注释去掉,789就会最后执行。

单核的时候其实goroutine并不是真的“并行”,goroutine都在一个线程里,它们之间通过不停的让出时间片轮流运行,达到类似并行的效果。

如果我在123,或者456之前加 time.Sleep(time.Second)。那么CPU的资源又会转让回主进程。

当一个goroutine发生阻塞,Go会自动地把与该goroutine处于同一系统线程的其他goroutines转移到另一个系统线程上去,以使这些goroutines不阻塞,主线程返回的时候goroutines又进入runqueue

下面这段代码:

import (

"fmt"

"runtime"

)

var quit chan int = make(chan int)

func loop() {

for i := 0; i < 100; i++ { //为了观察,跑多些

fmt.Printf("%d ", i)

}

quit <- 0

}

func main() {

runtime.GOMAXPROCS(1)

go loop()

go loop()

for i := 0; i < 2; i++ {

<-quit

}

}

会打印什么呢?

runtime.GOMAXPROCS(2)改成双核cpu,又会打印什么呢?

我们能看到,双核cpu的时候,goroutine会真正的并发执行而不是并行。他们会抢占式的执行。

参考https://studygolang.com/articles/1661

python

python是有多线程的,但是python有gil影响了他的多cpu利用。

GIL是CPython中特有的全局解释器锁

这把锁在解释器进程中是全局有效的,它主要锁定Python线程的CPU执行资源。

想要执行多核的进程需要满足2个条件

被操作系统调度出来【操作系统允许它占用CPU】

获取到GIL【CPython解释器允许它执行指令】

python在单核cpu上执行没有问题,这个线程总能获得gil,但是在多核的时候,线程会出现竞争,GIL只能同时被一个线程申请到,没申请到的就会被阻塞,就会一直处于闲置状态。

到线程切换时间然后睡眠,被唤醒之后获取gil又失败,恶性循环。

特别是计算型线程,会一直持有gil。

GIL 可以被 C 扩展释放,Python 标准库会在每次 I/O 阻塞结束后释放 GIL,因此 GIL 不会对 I/O 服务器产生很大的性能影响。因此你可以 fork 进程或者创建多线程来创建网络服务器处理异步 I/O,GIL 在这种情况下并没有影响。

解决方案:

使用python3.4或更高版本(对GIL机制进行了优化)

使用多进程替换多线程(多进程之间没有GIL,但是进程本身的资源消耗较多)

指定cpu运行线程(使用affinity模块)

全IO密集型任务时使用多线程

协程 (gevent模块)

Python 3.2开始使用新的GIL。新的GIL实现中用一个固定的超时时间来指示当前的线程放弃全局锁。在当前线程保持这个锁,且其他线程请求这个锁时,当前线程就会在5毫秒后被强制释放该锁。

总结

node是没有多线程的利用的,只能用多进程来利用多核cpu,python因为gil的问题,也没法完全利用多线程,但是有一些神奇的方案可以利用比如指定cpu运行。

go的实现是比较好的,毕竟是后来的语言,可以多核跑协程,来利用cpu

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

水晶底是什么材质_蓝宝石水晶镜面,贵是有道理的!

表友们在选择手表的时候&#xff0c;常常会在意机芯、性能等&#xff0c;但是你第一眼爱上的往往是它的外观。在手表上&#xff0c;有一样部件&#xff0c;你总是最先看到&#xff0c;占据着你视线的C位&#xff0c;但是你却总是忽略它。这个部分就是表镜&#xff0c;这个重要却…

str计算机中代表什么,STR到底是待机还是休眠

1。为什么需要待机、休眠尽管电脑硬件运行速度越来越快&#xff0c;但操作系统的体积也在不断膨胀&#xff0c;使得电脑开、关机时&#xff0c;启动、关闭的程序越来越多&#xff0c;花费时间也越来越漫长。因此如何让电脑能够快速启动、一开机就进入Windows&#xff0c;就成为…

科骏达导航端口测试软件,不用端口检测工具也可以知道机器端口,波特,分辨率...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼1. 富威&#xff1a; COM2/48002. 索菱、索莱特&#xff1a; COM3/96003. 凯振&#xff1a; COM2/96004. 路特仕、图音&#xff1a; COM2/96005. 卡仕达、科骏达&#xff1a; COM1/9600或COM6/48006. 欧华&#xff1a; COM2/96007.…

dedecms 漏洞_dedescan一款织梦漏洞扫描器

dedescan是一款可以扫描所有已公开的dedecms漏洞的扫描器。... ... ... ... ... ... …

post获取重定向的链接 python_欧美音乐网站Python爬虫项目实战

爬虫项目实战0x01 目标分析最近发现一个比较好的欧美音乐下载网站&#xff0c;可以下载大部分高质量欧美音乐。该爬虫项目要实现自动化批量获取用户想要下载的音乐。本文从网站分析、爬虫设计、代码实现三个方面出发&#xff0c;系统介绍该爬虫项目。项目完整代码在Github中可以…

中国志愿者服务器注册,如何注册成为志愿者?中国志愿服务网注册流程

西宁市团员、团干、青年志愿者个人和组织网上注册方式为“志愿汇”和“全国志愿服务信息系统(www.chinavolunteer.cn)”两个网站平台双线注册。志愿者注册流程基本操作指引一、PC电脑端操作注&#xff1a;本篇内容较多&#xff0c;建议先“收藏”文章或点击底部“在看”。1、PC…

iview 级联选择组件_iviewui级联选择 如何自定义?

export default {data () {return {value2: [jiangsu, suzhou, zhuozhengyuan],data: [{value: beijing,label: 北京,children: [{value: gugong,label: 故宫},{value: tiantan,label: 天坛},{value: wangfujing,label: 王府井}]}, {value: jiangsu,label: 江苏,children: [{va…

python s d是什意思_python里d是什么意思

python中的fd()是turtle模块中的一个方法。fd 方法的实参是像素距离。turtle模块&#xff1a;它可以让你使用海龟图形&#xff08;turtle graphics&#xff09;绘制图像 turtle模块其中的函数&#xff1a; 1&#xff09;turtle.pensize()&#xff1a;设置线条的粗细&#xff1b…

计算机二级如何接受审阅者修订,操作方法 合并修订文档 步骤1 要求审阅者

工作中&#xff0c;经常需要将文档交予多人同时审阅&#xff0c;那么如何实现让多人同时修改一个文档呢?解决方案审阅者在修订模式下修改文档&#xff0c;再将所有的修订文档合并。操作方法合并修订文档步骤1 要求审阅者&#xff0c;在修订模式下&#xff0c;修改文档&#xf…

vue中的uri_浅谈vue-resource和vue-axios的区别

可能有的人对vue-resource 和vue-axios比较陌生&#xff0c;也可能用到了都不知道。他其实就是我们vue请求里面的 this.$http.*** 和 this.axios.***vue-resourcevue-resource是Vue.js的一款插件&#xff0c;它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说&…

open表和closed表_011 Ruby 多Word表写入Excel

Hey&#xff0c;最近有很多粉丝私信询问&#xff0c;2020年已过半&#xff0c;又该统计半年报表信息了。你关心的是&#xff0c;Ruby能否像VBA、Python一样&#xff0c;实现多表格快速汇总&#xff1f;答案是肯定的。这期&#xff0c;为你讲解如何将多个Word表格汇总到Excel里。…

服务器响应options,HTTP发送对OPTIONS请求的响应[C]

在接收HTTP响应时出现Response is null错误。我正在开发一个使用行套接字的示例小型HTTP服务器C。HTTP发送对OPTIONS请求的响应[C]我的应用程序中实际上有2个服务器&#xff0c;一个是我用于提供HTML页面的标准Apache服务器&#xff0c;而我的小型服务器将只响应HTML页面中的Ja…

python数组排序sort_详解python中sort排序使用

1.前言 昨天一学妹问我一个关于python的问题&#xff0c;当时在外忙碌&#xff0c;没时间细看。今天看一下&#xff0c;咋一看我还真的不知道这个问题&#xff0c;bookinfo.sort(reverseTrue ,keylambda x:(x[1],x[1]/x[2]))是如何排序的。但是我猜测应该是按照第二个元素排序&…

审计工作存在的难点和问题_电力工程造价审计的难点与对策有哪些?学习安装电力造价广联达计价看这里!!...

目前电力工程审计的难度较大&#xff0c;对于审计人员的专业素质要求很高&#xff0c;尤其是在电力工程施工发生变动时&#xff0c;需要考虑工程的实际情况&#xff0c;及时对其进行工程造价审计。文章对电力工程造价审计中的难点进行了分析&#xff0c;并提出了相应的解决措施…

ajax实现一个前台的进度条,前台ajax实现上传文件并且有进度条

// ajax jQuery上传function UploadFile() {var xhrOnProgress function(fun) {xhrOnProgress.onprogress fun; //绑定监听//使用闭包实现监听绑return function() {//通过$.ajaxSettings.xhr();获得XMLHttpRequest对象var xhr $.ajaxSettings.xhr();//判断监听函数是否为函…

蒙特卡洛分析_随机模拟:马尔科夫链蒙特卡洛采样MCMC与EM算法「2.3」

最近学习了机器学习中的马尔科夫链蒙特卡洛(Markov Chain Monte Carlo, 简称MCMC) 相关的知识。主要内容包括&#xff1a;【1】蒙特卡洛原则&#xff0c;及其应用于采样的必要性(已经发布在头条)【2】用于求解最大似然、近似推断、期望问题的经典采样算法&#xff1a;Metropoli…

三维错切变换矩阵_图像的仿射变换

目录&#xff1a;概述图像基本变换仿射变换原理python实现一、概述图像的几何变换主要包括&#xff1a;平移、缩放、旋转、仿射、透视等等。图像变换是建立在矩阵运算基础上的&#xff0c;通过矩阵运算可以很快的找到不同图像的对应关系。理解变换的原理需要理解变换的构造方法…

app系统服务器出错怎么回事,app连接服务器出错

app连接服务器出错 内容精选换一换接口调用出错将无法获取建立相应隧道连接的必要信息&#xff0c;将无法正常建连云手机设备实例&#xff0c;具体报错示例如下&#xff1a;首先&#xff0c;尝试使用adb connect重新建立连接&#xff0c;依旧报错可通过查看安装目录下的日志adb…

js foreach 跳出循环_VUE.js

Vue.js模板语法vue.js使用了基于HTML的模板语法&#xff0c;允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据&#xff0c;其核心就是一个允许开发者采用简洁的模板语法来将数据渲染进DOM系统。使用各种组件来做成一个项目的话&#xff0c;需要结合单页应用。插值数据绑定最…

2异常处理_异常是什么?什么是常用类?

第一节 异常1. 异常的概念​ 异常(Exception) 即例外&#xff0c;程序没有按自己预想的结果运行出来&#xff0c;出现了非正常情况&#xff0c;即“程序得病了”。怎么让我们写的程序做出合理的处理&#xff0c;不至于崩溃是我们关注的核心。 异常机制就是当程序出现错误&#…