python 进程 小笔记(1)

进程:一个具有独立功能的程序关于某个数据集合的一次运行活动。 是一堆资源的集合,进程的执行必须在线程的基础上。

  进程中最少必须拥有一个线程。

进程与线程的区别?

(1)线程共享内存空间,进程的内存是独立的
(2)同一个进程的线程之间可以直接交流,两个进程想通信,必须通过一个中间代理来实现
(3)创建新线程很简单, 创建新进程需要对其父进程进行一次克隆
(4)一个线程可以控制和操作同一进程里的其他线程,但是进程只能操作子进程
(5)对主线程的修改有可能影响其他线程的运行,对一个父进程的修改不会影响子进程

进程知识点:
(1)进程的创建
  创建多线程,单线程只需把for语句去掉
import multiprocessing,threading,os
import time
def run(name):
    time.sleep(2)
    print("****************************************")
    print("module name :",__name__)
    print("parent process :", os.getppid())
    print("process id :", os.getpid())
    print("process info:",multiprocessing.current_process())
    print("threading info:",threading.current_thread())#进程里的主线程

    print("[%s] is process"%name)#进程里创建子线程
    print("****************************************")
    t = threading.Thread(target=handle , args=(name ,))
    t.start()

def handle(name):
    print("[%s] is thread" % name)
    print(threading.get_ident())

if __name__ =='__main__':

    run('main')
    for i in range(10):
        p = multiprocessing.Process(target=run , args=(i,))
        p.start()

 

(2)进程间的通信
  A、进程队列

    本质上是两个不同的列表,因为子进程创建的时候把父进程拷贝了一份,底层用pickle将子进程里的q序列化后放在一个两个进程都能碰到的地方, 然后父进程反序列化出来,从而实现了数据的交互。并不是修改同一份数据,只是完成了数据的传递。

import multiprocessing


def run(q):
   q.put([42,None,'leo'])
   print("child process :" , id(q))

if __name__ =="__main__":
    q = multiprocessing.Queue()
    p = multiprocessing.Process(target=run , args=(q,))
    p.start()
    print(q.get())
    print("parent process :", id(q))
  B、管道pies
import multiprocessing
def run(conn):
    
    while True:
        date = conn.recv()
        print("sub process:%s\n"%date)
        conn.send(date)


if __name__ =="__main__":
    parent_conn,sub_conn = multiprocessing.Pipe()
    p = multiprocessing.Process(target=run , args= (sub_conn,))
    p.start()
    while True:
        com = input("from parent>>\n:")
        parent_conn.send(com)
        print("parent process :%s"%parent_conn.recv())    
  C、Manage
import multiprocessing,os

def run(i,d,l,lock):
    lock.acquire()   #锁
    d[os.getpid()] = i
    # l.append(os.getpid())
    for a in range(1000):
        l[0] +=1
    print(l)
    lock.release()

if __name__ =="__main__":
    with multiprocessing.Manager() as manager:
    # 相当于 manager=multiprocessing.Manager()

        d = manager.dict()#生成一个字典,可在多个进程间共享和传递
        l = manager.list(range(5))
        p_list=[]
        lock =multiprocessing.Lock()#进程锁,主要作用是输出屏幕的数据不乱
        for i in range(10):
            p = multiprocessing.Process(target=run , args=(i,d,l,lock,))
            p_list.append(p)
            p.start()

        for i in p_list:  #等待子进程执行完毕
            i.join()

        print(d)
        print(l)
 
(3)进程池
  进程池:进程太多,启动时开销太大,导致系统变慢。需要限制每次启动进程的个数。
  必须先调用close()再调用join()
import multiprocessing,os,time

def run(i):
    time.sleep(2)
    print("[%s] is processing "%os.getpid())
    return i+100,'xxxx'

def Bar(*args):#主进程调用回调
    print('-->exec done:',args)
    print('callback from :',multiprocessing.current_process())

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=5)  #允许进程池里同时放入5个进程

    for i in range(10):#启动了10个进程,同一时间只有5个进程运行
        # pool.apply(func=run , args=(i,))#同步执行,串行
        #pool.apply_async(func=run, args=(i,))  # 异步执行,并行
        pool.apply_async(func=run, args=(i,),callback=Bar)  # 异步执行,并行,callback回调


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

  

 
 

猜你喜欢

转载自www.cnblogs.com/gtq7512/p/11375375.html