Python学习-八周四次课(12月14日)
八周四次课(12月14日)
15.3 多线程共享变量
15.4 线程池
python多线程可以使任务得到并发执行,但是有时候在执行多次任务的时候,变量出现“意外”。
- import threading,time
- n=0
- start=time.time()
- def b1(num):
- global n
- n=n+num
- n=n-num
- def b2(num):
- for i in range(1000000):
- b1(num)
- t1=threading.Thread(target=b2,args=(5,))
- t2=threading.Thread(target=b2,args=(8,))
- t1.start()
- t2.start()
- t1.join()
- t2.join()
- end=time.time()
- print(n)
- print(end-start)
执行结果:
- 18
- 0.7520430088043213
可见变量n从0变成了18,用时是0.75s,原因是计算机系统计算类似n=n+num是分两步计算的,先计算n+num的值放进内存中,然后再把计算的值赋值给n,正是这个间隙导致了变量出现“意外”。
这时候可以使用threading.Lock来把线程中的变量锁定,使用完再释放!
- import threading,time
- n=0
- lock=threading.Lock()
- start=time.time()
- def b1(num):
- global n
- n=n+num
- n=n-num
- def b2(num):
- for i in range(1000000):
- lock.acquire()#等待获取或获取修改变量的权限,并霸占它们
- b1(num)
- lock.release()#释放霸占的变量
- t1=threading.Thread(target=b2,args=(5,))
- t2=threading.Thread(target=b2,args=(8,))
- t1.start()
- t2.start()
- t1.join()
- t2.join()
- end=time.time()
- print(n)
- print(end-start)
执行结果:
- 0
- 3.335190773010254
虽然变量的值正确了,但慢了很多倍,效率大大的打折扣,多线程的优势也没凸显出来。
所以尽量使用局部变量来代替全局变量在线程中使用,这样可以避免效率的问题。
线程池:
1、安装
使用安装: pip installthreadpool
2、使用
(1)引入threadpool模块
(2)定义线程函数
(3)创建线程 池threadpool.ThreadPool()
(4)创建需要线程池处理的任务即threadpool.makeRequests()
(5)将创建的多个任务put到线程池中,threadpool.putRequest
(6)等到所有任务处理完毕theadpool.pool()
- import threadpool
- def ThreadFun(arg1,arg2):
- pass
- def main():
- device_list=[object1,object2,object3......,objectn]#需要处理的设备个数
- task_pool=threadpool.ThreadPool(8)#8是线程池中线程的个数
- request_list=[]#存放任务列表
- #首先构造任务列表
- for device in device_list:
- request_list.append(threadpool.makeRequests(ThreadFun,[((device, ), {})]))
- #将每个任务放到线程池中,等待线程池中线程各自读取任务,然后进行处理,使用了map函数,不了解的可以去了解一下。
- map(task_pool.putRequest,request_list)
- #等待所有任务处理完成,则返回,如果没有处理完,则一直阻塞
- task_pool.poll()
- if __name__=="__main__":
- main()
上面就是一个具体的线程池的使用流程
threadpool具体的定义如下:
- class ThreadPool:
- """A thread pool, distributing work requests and collecting results.
- See the module docstring for more information.
- """
- def __init__(self, num_workers, q_size=0, resq_size=0, poll_timeout=5):
- pass
- def createWorkers(self, num_workers, poll_timeout=5):
- pass
- def dismissWorkers(self, num_workers, do_join=False):
- pass
- def joinAllDismissedWorkers(self):
- pass
- def putRequest(self, request, block=True, timeout=None):
- pass
- def poll(self, block=False):
- pass
- def wait(self):
- pass

浙公网安备 33010602011771号