array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 并发编程--多进程1 - 爱码网

多道技术

实现原理:

1.空间复用

​ 统一时间,加载多个任务到内存中,多个进程之间内存区域需要相互隔离,这种隔离是物理层面的隔离,其目的是为了保证数安全

2.时间复用

​ 指的是,操作系统会在多个进程之间做切换执行

​ 切换任务的两种情况

​ 1.当一个进程遇到了IO操作 时会自动切换

​ 2.当一个任务执行时间超过阈值会强制切换

​ 注意:在切换前必须保存状态,以便后续恢复执行

​ 并且 频繁的切换其实也需要消耗资源

​ 当所有任务都没有IO操作时,切换执行效率反而降低,但是为了保证并发执行 必须牺牲效率

简单的总结就是切换加保存

有了多道技术,计算机就可以同时并发的处理多个任务

串行

自上而下运行

并行

真正的同时运行,必须具备多核CPU ,有几个核心就能并行几个任务,当任务数量超过核心数还是并发执行

并发

并发指的是多个任务同时被执行,并发编程指的是编写支持多任务并发的应用程序。

进程

进程指的是正在运行的程序,是一系列过程的统称,也是操作系统在调度和进行资源分配的基本单位

进程是实现并发的一种方式

一个程序可以产生多个进程

PID和PPID

PID:系统给进程的编号

PPID:当一个进程a开启了另一个进程b,那么a被称为b的父进程。当pycharm运行了py文件,那么pycharm就是py文件的父进程

并行与并发,阻塞与非阻塞

并发指的是,多个事件同时发生了,需要一直切换完成

并行指的是,多个事件同时进行,互不影响

阻塞状态是因为程序遇到了IO操作,或是sleep,导致后续的代码不能被CPU执行

非阻塞与之相反,表示程序正在被CPU执行。

进程有三种状态,就绪态,运行态,阻塞态

python中实现多进程

python中开启子进程的两种方式

方式1:实例化Process类

from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running ')
    time.sleep(3)
    print('f{name} is fone')
if __name__=='__main__':
    #在windows系统之上,开启子进程的操作一定要放在这个里面
	#Process(target=task,kwargs={'name':egon})
    p=Process(target=task,args=('jack',))#参数放在元祖里
	p.start()	# 向操作系统发送请求,操作系统会申请内存空间,然后把父进程的数据拷贝给子进程,作为子进程的初始状态
    print('主')
    

方式2:继承Process,并覆盖run方法

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super(MyProcess,self).__init__()
        self.name=name

    def run(self):
        print('%s is running' %self.name)
        time.sleep(3)
        print('%s is done' %self.name)
if __name__ == '__main__':
    p=MyProcess('jack')
    p.start()
    print('主')

需要注意的是

1.在windows下 开启子进程必须放到__main__下面,因为windows在开启子进程时会重新加载所有的代码造成递归创建进程

2.第二种方式中,必须将要执行的代码放到run方法中,子进程只会执行run方法其他的一概不管

3.start仅仅是给操作系统发送消息,而操作系统创建进程是要花费时间的,所以会有两种情况发送

3.1开启进程速度慢于程序执行速度,先打印”主“ 在打印task中的消息

3.2开启进程速度快于程序执行速度,先打印task中的消息,在打印”主“

进程间内存相互隔离

在一个进程内修改了全局变量,其他进程不受影响。就像是运行两个文件,一个修改了,另外一个不受影响。

from multiprocessing import Process
import time
x=1000
def task():
    global x
    x=0
    print('儿子死啦',x)


if __name__ == '__main_
    print(x)
    p=Process(target=task)
    p.start()
    time.sleep(5)
    print(x)
    
###
1000
儿子死啦 0
1000

join函数:

可以让一个进程等待另一个进程结束后再运行

from multiprocessing import Process
import time

x=1000

def task():
    time.sleep(3)
    global x
    x=0
    print('儿子死啦',x)
if __name__ == '__main__':
    p=Process(target=task)
    p.start()

    p.join() # 让父亲在原地等,如果不加join函数,则会先执行print(x)
    print(x)
    
from multiprocessing import Process
import time,random

x=1000

def task(n):
    print('%s is runing' %n)
    time.sleep(n)

if __name__ == '__main__':
    start_time=time.time()

    p1=Process(target=task,args=(1,))
    p2=Process(target=task,args=(2,))
    p3=Process(target=task,args=(3,))
    p1.start()
    p2.start()
    p3.start()

    p3.join() #3s
    p1.join()
    p2.join()

    print('主',(time.time() - start_time))

    start_time=time.time()
    p_l=[]
    for i in range(1,4):
        p=Process(target=task,args=(i,))
        p_l.append(p)
        p.start()
    for p in p_l:
        p.join()
    
    print('主',(time.time() - start_time))

Process对象常用属性

from multiprocessing import Process
def task(n):
    print('%s is runing' %n)
    time.sleep(n)

if __name__ == '__main__':
    start_time=time.time()
    p1=Process(target=task,args=(1,),name='任务1')
    p1.start() # 启动进程
    print(p1.pid) # 获取进程pid
    print(p1.name) # 获取进程名字
    p1.terminate() # 终止进程
    p1.join() # 提高优先级
    print(p1.is_alive()) # 获取进程的存活状态
    print('主')

孤儿进程和僵尸进程

孤儿进程:

指的是开启子进程后,父进程先于子进程终止了,那这个子进程就称之为孤儿进程。

孤儿进程是无害的,有其存在的必要性,在父进程结束后,其子进程会被操作系统接管。

僵尸进程:

指的是当父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程会成为一个僵尸进程,这种情况只在linux下出现。因为windows中进程完全是独立的没有任何关联。

如果父进程先退出,子进程被操作系统接管,子进程退出后操作系统会回收其占用的相关资源,

python已经帮我们自动处理了僵尸进程的回收工作。

相关文章: