进程&进程池

进程

服务器中, s.listen(n) n不能无限大,以为内存不可能无限大,n表示内存同一时间接纳的等待连接数,可以看成一个(队列),取出一个拿去建立连接,然后再放进一个,队列中一直保持n个连接

请求.

补充一点:
  print() 是计算操作, 计算机中除了IO,都是计算(PS:cpu干的活都是计算).

进程的运行回收机制: 主进程等子进程运行完 才回收子进程,自己再关闭

父进程杀死了,子进程就会变成孤儿进程(甚至变成僵尸进程)

非常重要的一个概念:
  运行py文件,在进程中显示的不是xx.py, 而是解释器的python.exe,
  是因为代码只是一堆符号,没有意义,只有把代码传给python解释器,python解释器解释后,调用的python解释器的功能.
  实际上用的python解释器的功能,所以进程中显示运行的是python.exe解释器而不是xx.py文件.
  (举个例子:py文件中一行代码为print,那么python解释器就会调用自己的打印功能)

 

查看进程号:

import os
print(os.getpid())    #打印进程id号
print(os.getppid())     # 父进程id号

查看进程和杀死进程:

cmd解释器中:
tasklist |findstr python  #管道符 过滤 查看python关键字 进程
干掉python进程
tskill python

tskill 进程name
tskill 进程pid号

运行环境的父进程:

运行一个xxx.py (python3环境下) , 打印这个进程的父进程id号,发现是pycharm 的id号.为什么呢?
    pycharm 运行 python3 xxx.py , 然后 产生一个 python.exe 进程.所以pycharm是这个python.exe的父进程
    (pycharm 运行 python3 xxx.py     ====>>   python.exe)

PS:如果在cmd中运行,这个python.exe的父进程就是cmd的id号

jion():

jion(),主进程等待子进程

import time
from multiprocessing import Process


def task(name):
    time.sleep(2)
    print('%s' % name)


if __name__ == '__main__':
    p = Process(target=task,args=('kitty',))
    p.start()
    p.join()                    #等 子进程运行完毕,主进程才继续往下运行
    print('主进程')

如果有多个子进程:p1 p2 p3

p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
# 这种情况下,相当于串行(等待上一个进程执行完,才继续往下执行下一个进程)

-

p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
# 这种情况下,是并发(PS:join()的顺序先后没关系)

可以简洁点:

p_l = [p1,p2,p3]
for p in p_l:
    p.start()
for p in p_l:
    p.join()

name = None

进程名可以自定义:

if __name__ == '__main__':
    p = Process(target=task,args=('kitty',),name='haha')
    p.start()
    p.join()
    print(p.name)           #haha  自定义子进程名字
    print('主进程')

terminate(): 杀死进程

is_alive(): 判断进程是否活着

def task(name):
    time.sleep(2)
    print('%s' % name)


if __name__ == '__main__':
    p = Process(target=task,args=('kitty',))
    p.start()
    p.terminate()               #杀死进程p
    print(p.is_alive())         #True  之所以是True,而不是False,是因为杀死进程p.terminate()只是发了一个信号,主进程马上就判断
                                        # (杀死进程需  要时间)
    print('主进程')

注意:
  慎用, 如果儿子进程开了个孙子进程,就会产生孤儿进程(比较危险)
  现实场景也很少这种操作

进程池

1.进程池中存放的就是进程,只不过加上了数目的限制,

2.进程池造出来后,不会开新的进程,从始至终就是造进程池时定义的数目

3.等进程池中的所有进程都完毕,先关门,在等(shutdown(wait = True))

示例:

import time
from concurrent.futures import ProcessPoolExecutor


def task(name):
    time.sleep(2)
    print('%s' % name)


if __name__ == '__main__':
    p = ProcessPoolExecutor(4)          # 立刻造好4个进程
    # p.submit(task,'kitty1')
    # p.submit(task,'kitty2')
    # p.submit(task,'kitty3')
    # p.submit(task,'kitty4')
    for i in range(1, 11):
        p.submit(task, 'kitty%s' % i)       #submit() 往里面丢任务
    print('主进程')

提交/调用 任务的方式

1.同步调用:

  提交/调用一个任务,然后就在原地等着,等到该任务执行完毕拿到结果,再执行下一行代码

2.异步调用:

  提交/调用一个任务,不在原地等着,直接执行下一行代码.

 

from concurrent.futures import ProcessPoolExecutor

新版本中(新模块中)根本就没有同步接口,只有异步接口,就是submit()

新版本中:

  关门+等

  shutdown(wait = True)

---------------------------------------------------------------------------------------


from multiprocessing import Process, Pool

老版本中(Pool)中有个同步接口 p.apply()

老版本中:

  关门+等

  pool.close()

  pool.join()
--------------------------------------------------------

同步调用方式:

  开进程 等待 再开,再等这种提交任务的方式,想当于串行

for p in p_l:
    p.start()
    p.join()

示例:

import time
from concurrent.futures import ProcessPoolExecutor


def task(name, n):
    time.sleep(1)
    print('%s' % name)
    return n**2


if __name__ == '__main__':
    p = ProcessPoolExecutor(4)
    p_l = []
    for i in range(1, 11):
        obj = p.submit(task, 'kitty%s' % i, i)
        print(obj.result())                 #相当于start和join连用
    print('主进程')

# kitty1
# 1
# kitty2
# 4
# kitty3
# 9
# kitty4
# 16
# kitty5
# 25
# kitty6
# 36
# kitty7
# 49
# kitty8
# 64
# kitty9
# 81
# kitty10
# 100
# 主进程

异步调用方式:

for i in range(10):
    p.submit(func,'xx')

示例:

import time
from concurrent.futures import ProcessPoolExecutor


def task(name, n):
    time.sleep(1)
    print('%s' % name)
    return n**2


if __name__ == '__main__':
    p = ProcessPoolExecutor(4)
    p_l = []
    for i in range(1, 11):
        obj = p.submit(task, 'kitty%s' % i, i)      # obj是个对象,通过对象拿到结果
        p_l.append(obj)
    p.shutdown(wait = True)            #shutdown(wait = True) 等,但是前提是进程池中不能再放进新的任务了,否则数目不准确(先关门+等)
    print('主进程')
    for i in p_l:
        print(i.result())

# kitty1
# kitty2
# kitty3
# kitty4
# kitty5
# kitty6
# kitty7
# kitty8
# kitty9
# kitty10
# 主进程
# 1
# 4
# 9
# 16
# 25
# 36
# 49
# 64
# 81
# 100

 

posted @ 2017-10-28 22:53  静静别跑  阅读(350)  评论(0编辑  收藏  举报