进程

进程,至少包含一个线程

IO操作不占用CPU,从内存,硬盘,网络读数据这都叫IO操作

计算才占用CPU   python多线程,不适合CPU密集操作性任务,适合IO操作密集型任务

创建新进程需要对其父进程进行一次克隆

一个线程可以控制和操作同一进程里的其他线程,但是进程只能操作子进程

多进程multiprocessing

import multiprocessing,threading
import time

def run(name):
    time.sleep(1)
    print("hello",name)
    t=threading.Thread(target=thread_run)   # 进程里面实现多线程
    t.start()



def thread_run():
    print(threading.get_ident())


if __name__=="__main__":

    for i in range(10):

        p=multiprocessing.Process(target=run,args=('jim %s'%i,))
        p.start()
    # p.join()
多进程
# -*-coding:utf-8-*-
# Author:sunhao

import os,multiprocessing



def info():
    print("父进程",os.getppid())
    print("进程id",os.getpid())
    print("\n\n")


def f():
    info()



if __name__ == '__main__':   #子进程都是由父进程生成的
    info()
    p=multiprocessing.Process(target=f)
    p.start()
父进程和子进程

 

进程间通讯

不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

1.Queues

import multiprocessing

def f(qq):

    qq.put([42,None,'hello'])



if __name__=='__main__':


    que=multiprocessing.Queue()

    p=multiprocessing.Process(target=f,args=(que,))  # 将父进程que传给子进程      中间通过pickle序列化 实际上是有两个que
    p.start()
    print(que.get())

2.Pipes管道

# -*-coding:utf-8-*-
# Author:sunhao

import multiprocessing

def f(conn):

    conn.send([42,None,'lily1'])
    conn.send([42, None, 'lily2'])
    print("from child")
    #print(conn.recv())
    conn.close()




if __name__ == '__main__':

    parent_conn,child_conn = multiprocessing.Pipe()  #生成一个管道实例 两个返回变量  相当于电话线的两头  这头传递到那头  

    p=multiprocessing.Process(target=f,args=(child_conn,))
    p.start()
    print(parent_conn.recv())
    print(parent_conn.recv())
    parent_conn.send("from parent")
    p.join()

进程间共享数据Manager

# -*-coding:utf-8-*-
# Author:sunhao


import multiprocessing,os

def f(d,l):

    d[os.getpid()]=os.getpid()
    l.append(os.getpid())



if __name__=='__main__':

    with multiprocessing.Manager() as manager:
        d=manager.dict() #生成一个字典 可在多个进程间共享和传递
        l=manager.list(range(5)) #生成一个列表 可在多个进程间共享和传递
        


        p_list=[]

        for i in range(10):
            p=multiprocessing.Process(target=f,args=(d,l))
            p.start()

            p_list.append(p)

        for res in p_list:

            res.join()

        print(d)
        print(l)
进程间数据共享

 

进程同步锁

进程里为什么需要锁?

因为屏幕共享,加锁屏幕上不会乱

 

from multiprocessing import Process, Lock
 
def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()
 
if __name__ == '__main__':
    lock = Lock()
 
    for num in range(10):
        Process(target=f, args=(lock, num)).start()   #要把lock当参数 传进去 

 

进程池

同一时间有几个进程在cpu上运行

线程没有线程池的原因是线程的开销太小,而启动进程的开销比较大

 

进程池中有两个方法:

 

  • apply   串行
  • apply_async  并行  里边有个回调函数

 

# -*-coding:utf-8-*-
# Author:sunhao

import multiprocessing
import time,os

def Foo(i):
    time.sleep(2)
    print("in process",os.getpid())
    return i+100

def bar(arg):
    print("exec done",arg,os.getpid())




if __name__=='__main__':

    pool = multiprocessing.Pool(3)    #允许进程池里放入5个进程
    print("主程序pid",os.getpid())

    for i in range(10):

        # pool.apply(func=Foo,args=(i,))              #apply串行  apply_async并行
        # pool.apply_async(func=Foo, args=(i,))
        pool.apply_async(func=Foo, args=(i,),callback=bar)   #callback ==回调  回调是等一个进程执行完毕后  在执行callback的函数
    print("done")


    pool.close()   #先关闭再join
    pool.join()   #进程池中进程执行完毕后在关闭,如果注释,那么程序直接关闭