7、进程与线程

xiaoxiao2021-03-01  16

1、多进程

A:Unix/Linux进程(windows不支持)

 

import os # fork创建一个子进程 pid = os.fork() # 子进程返回0 if pid == 0: print 'this is child : %s ,parent:%s' % (os.getpid(),os.ppid()) else print 'this is parent: %s' % os.getpid()

 

B:multiprocessing 夸平台支持多进程

 

#coding=utf-8 from multiprocessing import Process import os def myProc(name): print 'processing name :%s :%s' %(name,os.getpid()) if __name__ == '__main__': print 'Parent process : %s' % os.getpid() # 创建一个进程 # target 进程启动时运行的方法,args第一个参数是进程名称 pro = Process(target=myProc,args=('test',)) pro.start() # 启动子进程 运行myPro方法 pro.join() # 子进程运行完后再往下执行 print 'end'

 

C:Pool 启动大量进程

 

from multiprocessing import Pool import os,time,random def myPro(name): print 'Run task %s (%s)...' % (name, os.getpid()) start = time.time() # 进程休眠 time.sleep(random.random() * 2) # 秒 end = time.time() print 'Task %s runs %0.2f seconds.' % (name, (end - start)) if __name__ == '__main__': # 设置同时可以运行多个进程,默认cpu个数 p = Pool() for i in range(5): # 创建进程,并运行进程 p.apply_async(myPro,args=(i,)) print '----------start-------------' #time.sleep(30) p.close() # 保证之后不再添加新的进程 p.join() # 子进程都结束后再运行下边的程序 print '----------end---------------'

 

D:进程之间的通信

 

# Pipes一对一通信,效率高,Queue基于Pipes,可以多对多通信 # 以Queue为例 from multiprocessing import Process,Queue import os,time,random # 写 def write(q,name): for v in ['1','2','3','4','5','6','7','8','9','0']: q.put(v) print 'who: %s write %s' % (name,v) time.sleep(random.random()*2) # 读 def read(q,name): while True: #时刻在读取Queue中数据 print 'who: %s read %s' % (name,q.get(True)) time.sleep(random.random()*1) if __name__ == '__main__': q = Queue() # 写 进程 w = Process(target=write,args=(q,'w')) # 读 进程 r = Process(target=read,args=(q,'r')) w.start() r.start() w.join() r.terminate() # 强制停止进程

 

2、多线程(进程中有一个或多个线程)

A:threading (对thread进行封装)

 

import time,threading # 线程执行的代码 def mydef(): print 'who run : %s' % threading.current_thread().name n = 0 while n < 5 : n = n + 1 print 'thread %s --- %d' % (threading.current_thread().name,n) time.sleep(1) print 'end: %s' % threading.current_thread().name if __name__ == '__main__': t1 = threading.Thread(target=mydef,name='thread_1') t2 = threading.Thread(target=mydef,name='thread_2') t1.start() t2.start() t1.join() t2.join()

 

B:Lock (线程锁,避免变量同时被多个线程操作)

 

import time,threading number = 0 def change(n): # 该数据同时被两个线程操作,造成数据的混乱 global number number = number + n number = number - n def run(n): for i in range(1000): change(n) print number ,'\n' if __name__ == '__main__': thread1 = threading.Thread(target=run,args=(5,)) thread2 = threading.Thread(target=run,args=(8,)) thread1.start() thread2.start() thread1.join() thread2.join() print number # 使用 Lock() 实现变量的同步,将上边的run方法修改 # 即 全局变量的操作必须加锁 def run2(n): for i in range(1000): # 将该代码段锁住,是能同时被一个线程访问 lock.acquire() try: change(n) finally: # 释放线程锁 lock.release() print number ,'\n'

 

C:多核CPU

        多核可以同时执行多个线程。

        但是在Python中,有GIL(Global Interpreter Lock)锁,故线程被上锁,是交替运行的。

 

        所以,在多核CPU中运用线程是徒劳的。

 

3、ThreadLocal

在线程中, 局部变量的传递是通过方法的参数传递的,但是调用多层的方法时,会很麻烦。

使用ThreadLocal可以解决局部变量传递的问题。

import threading # local是一个dict 键值对 local = threading.local() def run(name): # 设置传递局部变量参数 local.name = name # 因为是局部变量,所以不需要设置锁 for i in range(1000): addB() def addB(): # 获取局部变量参数 name = local.name + '+B' print '%s = %s \n' % (threading.current_thread().name,name) if __name__ == '__main__': p1 = threading.Thread(target=run,args=('p1',),name='thread_1') p2 = threading.Thread(target=run,args=('p2',),name='thread_2') p1.start() p2.start() p1.join() p2.join()

 

转载请注明原文地址: https://www.6miu.com/read-3100161.html

最新回复(0)