2019-05-15
多进程
一个进程是由多个线程组成的,一个进程至少有一个线程
<font color='maroon'>在Linux和Mac系统中</font>
</br>
执行到fork()函数时,会创建当前父进程的克隆版(子进程),父进程里的fork()函数返回子进程的ID,而子进程的fork()返回0,但是子进程可以通过getpid()获得父进程的ID
import os
print('Process (%s) start...' % os.getpid())
pid=os.fork()
if pid==0:
print('I am child process (%s) and my parent is %s.' % (os.getpid(),os.getpid()))
else:
print('I (%s) just created a child process (%s).' % (os.getpid(),pid))
<font color='maroon'>基于Windows</font>
from multiprocessing import Process
import os
def run_proc(name):
print('Run child process %s (%s)...' % (name,os.getpid()))
if _name_='_main_':
print('Parent process %s.' % os.getpid())
p=Process(target=run_proc,args=('test'))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
如果要启动大量的子进程,可以同进程池的方式批量创建子进程:
from multiprocess import Pool
import os,time,random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start=time.time()
time.sleep(random.random()*3)
end=time.time()
print('Task %s runs %0.2f seconds.' % (name,(end-start)))
if _name_='_main_':
print('Parent process %s.' % os.getpid())
p=Pool(4)
for i in range(5):
p.apply_async(long_time_task,args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subproccesses done.')
多线程
threading(高级模块),启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行。</br>
<font color='maroon'>线程是应用程序中工作的最小单元</font>
新线程执行的代码
import time,threading
def loop():
print('thread %s running...' % threading.current_thread().name)
n=0
while n<5:
n+=1
print('thread %s >>>%s' % (threading.current_thread().name,n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
print('thread %s is running...' % threading.current_thread().name)
t=threading.Thread(target=loop,name='LoopThread') #threading模块创建thread实例
t.start() #开始执行
t.join()
print('thread %s ended.' % threading.current_thread().name)
多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时又要小心死锁的发生
import time,threading
balance=0
lock=threading.Lock()
def change_it(n):
global balance
balance=balance+n
balance=balance-n
def run_thread(n):
for i in range(100000):
lock.acquire()
try:
change_it(n)
finally:
lock.release()
t1=threading.Thread(target=run_thread,args=(5,))
t2=threading.Thread(target=run_thread,args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
<font size=5em><font color='maroon'>在多线程环境下,每个线程都有自己的数据。一个数据使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局编程的修改必须加锁。</font></font>
import threading
#创建全局ThreadLocal对象:
local_school=threading.local()
def process_student():
#获取当前线程关联的student:
std=local_school.student
print('Hello,%s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
#绑定ThreadLocal的student:
local_school.student=name
process_student()
t1=threading.Thread(target=process_thread,args=('Alice',),name='Thread-A')
t2=threading.Thread(target=process_thread,args=('Bobs',),name='Thread_B')
t1.start()
t2.start()
t1.join()
t2.join()
一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题