ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

进程.

2019-03-02 18:39:47  阅读:175  来源: 互联网

标签:__ name Process print 进程 import


操作系统的背景知识:
操作系统的作用:
1.封装了丑陋复杂的接口,提供了良好的抽象接口
2.管理.调度程序,并将多个进程或者程序对硬件资源的竞态请求变的有序化
多道技术:
产生背景:针对于单核,实现并发
空间上的复用:内存中存在多道程序
时间上的复用:
1.遇到io口就切换
2.一个进程长时间被CPU处理的时,操作系统会强硬的将cpu调出去处理下一个进程
进程:是计算机中关于数据集合上的一次运行活动,是系统资源分配和调度的基本单位
是操作系统结构的基础
也是正在运行程序的实例

进程的调度: 先来先服务调度算法,
短作业优先调度算法,
时间片轮转法,
多级反馈队列

进程的并行并发:
并行:指的是两个或者多个cpu同时分别执行两个或者多个进程
并发:指的一个cpu对多个进程轮流交替使用
区别:虽然给人的感觉是同时执行的,但是并发是在多个进程之间交替执行

进程的同步异步:
同步:一个任务的完成需要依赖另一个任务的完成
异步:任务的完成不需要被等待的任务完成

进程的三态状态:就绪,阻塞,运行

进程的创建和结束:
创建:UNIX中调用的是fork
Windows是CreateProcess
创建子进程:UNIX和Windows
相同点:都会将父进程复制一份,存放到另一个地址空间,也就是子进程,但是两个进程之间在地址空间的操作没有关系
不同点:NUIX中子进程的地址空间是父进程的一个副本,存在只读的共享内存区的
windows的子进程空间跟父进程的进程空间多一些东西

在python程序中的进程操作:
multiprocess模块:是python中的一个操作,管理进程的包.包中几乎包含了跟进程有关的所有子模块
大致分为四类:
创建进程部分
进程同步部分
进程池部分
进程之间数据共享


1.创建进程部分(multiprocess.process模块)
  process模块是一个创建进程的模块,借助这个模块就可以完成进程的创建
  创建进程的时候windows必须要用if __name__=__main__():
  在进程中,main之上的代码都是子进程的代码,主进程只有在子进程结束后才算真正意义上结束
import time
from multiprocessing import Process #导入Process模块
def func(name):
    time.sleep(0.1)
    print('hello',name)
    print('我是子进程')
if __name__ == '__main__':
    p = Process(target=func,args=('智障',))
    #由Process实例化出的一个对象,表示一个子进程中的任务(尚未启动)
    p.start()#启动进程
    time.sleep(1)
    print('我是主进程')

 

  通过类的方式创建一个进程:
from multiprocessing import Process
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print('%s正在吃饭'%self.name)
if __name__ == '__main__':
    p = MyProcess('alex')
    p.start()
    p.join()

 


  p.jion()的用法:是主进程等待p进程(子进程)的结束后再结束
import time
from multiprocessing import Process
def func():
    print('子进程开始')
    time.sleep(1)
    print('子进程结束')
if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    p.join()
    print('主进程')
# 结果:
    子进程开始
    子进程结束
    主进程

 

  多个进程运行时,join的用法: 多个进程执行的时候,join的个数和进程个数一样且必须连续放置
from multiprocessing import Process
def func(name):
    print('hello',name)
if __name__ == '__main__':
    p_l = []
    for i in range(5):
        p = Process(target=func,args=('智障',))
        p.start()
        p_l.append(p)
    for p in p_l:
        p.join()
    print('主程序')

 


  查看进程属性:
查看进程的id:需要调用带os模块 (os.getpid , os.getppid)
import os
from multiprocessing import Process
def func():
    print('子进程',os.getpid())
    # print('主进程',os.getppid())
if __name__ == '__main__':
    print('主进程', os.getpid())
    for i in range(5):
        p = Process(target=func)
        p.start()
在子程序中os.getpid()可以查看子进程id
在主程序中os.getpid()可以查看本进程id

 


验证进程之间的数据隔离:
进程之间的数据是隔离的,
from multiprocessing import Process
n = 100
def func():
    global n
    n = 2
if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    print(n)




守护进程:会随着主程序的结束而结束
  1.守护进程会在主进程代码运行结束后就终止

  2.守护进程内无法再开启子程序,否则抛出异常
# 主进程必须在子进程结束后回收子进程的代码后才算真正的结束
# 必须在p.start()前设置守护进程
# 守护进程若是主进程结束后,就不会再执行
import time
from multiprocessing import Process
def foo():
    print(123)
    time.sleep(1)
    print("end123")
def bar():
    print(456)
    time.sleep(3)
    print("end456")
if __name__ == '__main__':
    p1 = Process(target=foo)
    p2 = Process(target=bar)
    p1.daemon = True
    p1.start()
    p2.start()
    time.sleep(2)
    print('主进程')
# 结果:
123
456
end123
主进程
end456

 

进程的其他用法:
p.teminate()关闭进程,但是不会立即关闭 ,所以is_live立刻查看的结果还可能是True
2.进程同步(multiprocess.Lock):为了维护数据的安全,牺牲了效率利用互斥锁
from multiprocessing import Process,Lock
import time
import os
def func(name,lock):
    lock.acquire()
    print('%s: %s 正在跑'%(name,os.getpid()))
    time.sleep(1)
    print('%s: %s已经跑完了'%(name,os.getpid()))
    lock.release()
if __name__ == '__main__':
    lock = Lock()
    p1 = Process(target=func,args=('小明',lock))
    p2 = Process(target=func,args=('小红',lock))
    p1.start()
    p2.start()

 

加锁可以保证多个进程修改同一个数据的时候,只能在同一时间一个程序进行修改,就是串行修改

加锁的方式使代码的效率变低,还要自己进行加锁处理,所以大部分都是采用管道和队列的方式
(基于消息的ipc机制,进程之间的通信)



3.进程间的通信 队列 multiprocess.Queue:
import  time
from multiprocessing import Process,Queue
def func(q):
    q.put([time.asctime(),'form alex','hello'])
if __name__ == '__main__':
    q = Queue()#参数为显示队列的里的元素个数
    p =Process(target=func,args=(q,))
    p.start()
    print(q.get())
    p.join()

 

 

JionableQueue()跟Queue的方法一样,但是多了几个
q.task_done()#使用此方法发出信号,表示q.get()返回的项目已经被处理;
如果调用的此方法次数大于从队列中删除的项目数量,将引发ValueError异常
q.join()生产者将使用此方法进行阻塞

 

 

# 生产者和消费者模型(欠着)

 

3.进程之间的数据共享(Manager模块)
  Manager提供可共享的数据类型但是不加锁操作的共享数据肯定会出错
from multiprocessing import Manager,Process,Lock
def work(dic,lock):
    with lock:#必须加锁才能保证数据的安全
        dic['count'] -=1
if __name__ == '__main__':
    lock = Lock()
    m = Manager()
    dic = m.dict({'count':100})#设置可共享数据
    p_L= []
    for i in range(100):
        p = Process(target=work,args=(dic,lock))
        p_L.append(p)
        p.start()
    for p in  p_L:
        p.join()
    print(dic)

 

 

 

4.进程池(Pool):方便了系统调用,节省了时间,实现并发效果

from multiprocessing import Process,Pool
import time
def func(i):
    i * i
    return 'i'*i
if __name__ == '__main__':
    start = time.time()
    p = Pool(4)#设置要开启进程数 默认为cpu的个数
    for i in range(50):
        p.apply_async(func,(i,))#异步提交 apply提交 async异步
    p.close()#关闭进程池 不允许再继续向这个池子添加任务了
    p.join()#阻塞,直到已经被提交的进程池中的任务全部结束
    print(time.time()-start)

 

返回值的获得

from multiprocessing import Pool
def func(i):
    i * i
    return 'i'*i
if __name__ == '__main__':
    p = Pool()
    ret_l = []
    for i in range(20):
        ret = p.apply_async(func,(i,))
        ret_l.append(ret)
        print(ret.get())
    # for ret in ret_l:
        print(ret.get())#获取返回值的时候必须是ret.get()
将返回值加入列表中循环打印

 

同步调用:

import os
import time
import random
from multiprocessing import Pool
def func(i):
    time.sleep(random.random())
    print(i,os.getpid())
if __name__ == '__main__':
    p = Pool()
    for i in range(20):
        ret = p.apply(func,(i,))
同步调用的时候 第一个进程执行完结束后才能执行,遇到io阻塞后,后面的程序都会被阻塞

Pool使用map的方法:
import time
from multiprocessing import Pool
def func(i):
    return 'i' * i
if __name__ == '__main__':
    p = Pool()
    ret_l = p.map(func,range(20))#第二个为可迭代的对象 得到结果是一个列表
    #map就是简单的appli_async的方式,并内置了close和join的功能
    for ret in ret_l:
        print(ret)

 

 

回调函数callback

标签:__,name,Process,print,进程,import
来源: https://www.cnblogs.com/shicongcong0910/p/10462331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有