首页 > 编程 > Python > 正文

Python 多线程Threading初学教程

2020-01-04 16:48:24
字体:
来源:转载
供稿:网友

1.1 什么是多线程 Threading

多线程可简单理解为同时执行多个任务。

多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。

1.2 添加线程 Thread

导入模块

import python/52576.html">threading

获取已激活的线程数

threading.active_count()

查看所有线程信息

threading.enumerate()

查看现在正在运行的线程

threading.current_thread()

添加线程,threading.Thread()接收参数target代表这个线程要完成的任务,需自行定义

def thread_job():  print('This is a thread of %s' % threading.current_thread())def main():  thread = threading.Thread(target=thread_job,)  # 定义线程   thread.start() # 让线程开始工作  if __name__ == '__main__':  main()

1.3 join 功能

因为线程是同时进行的,使用join功能可让线程完成后再进行下一步操作,即阻塞调用线程,直到队列中的所有任务被处理掉。

import threadingimport timedef thread_job():  print('T1 start/n')  for i in range(10):    time.sleep(0.1)  print('T1 finish/n')def T2_job():  print('T2 start/n')  print('T2 finish/n')def main():  added_thread=threading.Thread(target=thread_job,name='T1')  thread2=threading.Thread(target=T2_job,name='T2')  added_thread.start()  #added_thread.join()  thread2.start()  #thread2.join()  print('all done/n')if __name__=='__main__':   main()

例子如上所示,当不使用join功能的时候,结果如下图所示:

python,多线程,threading

当执行了join功能之后,T1运行完之后才运行T2,之后再运行print(‘all done')

python,多线程,threading

1.4 储存进程结果 queue

 queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

 (1)基本FIFO队列

 class queue.Queue(maxsize=0)

maxsize是整数,表明队列中能存放的数据个数的上限,达到上限时,插入会导致阻塞,直至队列中的数据被消费掉,如果maxsize小于或者等于0,队列大小没有限制

(2)LIFO队列 last in first out后进先出

class queue.LifoQueue(maxsize=0)

(3)优先级队列

class queue.PriorityQueue(maxsize=0)

视频中的代码,看的还不是特别明白

import threadingimport timefrom queue import Queuedef job(l,q):  for i in range(len(l)):    l[i]=l[i]**2  q.put(l)def multithreading():  q=Queue()  threads=[]  data=[[1,2,3],[3,4,5],[4,5,6],[5,6,7]]  for i in range(4):    t=threading.Thread(target=job,args=(data[i],q))    t.start()    threads.append(t)  for thread in threads:    thread.join()  results=[]  for _ in range(4):    results.append(q.get())  print(results)if __name__=='__main__':   multithreading()

运行结果如下所示

python,多线程,threadingpython,多线程,threading

图片截取来源:http://www.cnblogs.com/itogo/p/5635629.html

1.5 GIL 不一定有效率

Global Interpreter Lock全局解释器锁,python的执行由python虚拟机(也成解释器主循环)控制,GIL的控制对python虚拟机的访问,保证在任意时刻,只有一个线程在解释器中运行。在多线程环境中能,python虚拟机按照以下方式执行:

1.设置 GIL

2.切换到一个线程去运行

3.运行:

a.指定数量的字节码指令,或

b.线程主动让出控制(可以调用time.sleep(0))

4.把线程设置为睡眠状态

5.解锁GIL

6.重复1-5

在调用外部代码(如C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有python的字节码被运行,所以不会做线程切换)。

下面为视频中所举例的代码,将一个数扩大4倍,分为正常方式、以及分配给4个线程去做,发现耗时其实并没有相差太多量级。

import threadingfrom queue import Queueimport copyimport timedef job(l, q):  res = sum(l)  q.put(res)def multithreading(l):  q = Queue()  threads = []  for i in range(4):    t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)    t.start()    threads.append(t)  [t.join() for t in threads]  total = 0  for _ in range(4):    total += q.get()  print(total)def normal(l):  total = sum(l)  print(total)if __name__ == '__main__':  l = list(range(1000000))  s_t = time.time()  normal(l*4)  print('normal: ',time.time()-s_t)  s_t = time.time()  multithreading(l)  print('multithreading: ', time.time()-s_t)

运行结果为:

python,多线程,threading

python,多线程,threading

1.6 线程锁 Lock

如果线程1得到了结果,想要让线程2继续使用1的结果进行处理,则需要对1lock,等到1执行完,再开始执行线程2。一般来说对share memory即对共享内存进行加工处理时会用到lock。

import threadingdef job1():  global A, lock #全局变量  lock.acquire() #开始lock  for i in range(10):    A += 1    print('job1', A)  lock.release() #释放def job2():   global A, lock  lock.acquire()  for i in range(10):    A += 10    print('job2', A)  lock.release()if __name__ == '__main__':  lock = threading.Lock()  A = 0  t1 = threading.Thread(target=job1)  t2 = threading.Thread(target=job2)  t1.start()  t2.start()  t1.join()  t2.join()

运行结果如下所示:

python,多线程,threading

总结

以上所述是小编给大家介绍的Python 多线程Threading初学教程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对VEVB武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表