接着上篇继续跟着沫凡小哥学Python啦

1.1 什么是多线程 Threading

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

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

1.2 添加线程 Thread

导入模块

import 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 threading
import time
def 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功能的时候,结果如下图所示:

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

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 threading
import time
from queue import Queue
def 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()

运行结果如下所示

图片截取来源: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 threading
from queue import Queue
import copy
import time def 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)

运行结果为:

1.6 线程锁 Lock

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

import threading

def 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的更多相关文章

  1. python的多线程threading

    多线程threading 1.Thread创建线程: 上代码: #!/usr/bin/env python3 import threading import time def A(): t_name ...

  2. Python:多线程threading模块

    目录 Thread对象 Lock对象 local对象 Thread对象: 多任务可以由多进程完成,也可以由一个进程内的多线程完成.进程是由至少1个线程组成的. threading模块在较低级的模块 _ ...

  3. python之多线程 threading.Lock() 和 threading.RLock()

    0.目录 2. threading.Lock() 的必要性3.观察block4.threading.RLock() 的应用场景 1.参考 Thread Synchronization Mechanis ...

  4. Python学习【第26篇】:Python系列- 多线程(threading)

    线程的调用方式:threanding模块 import threading import time def sayhi(num): #定义每个线程要运行的函数 print("running ...

  5. Python的多线程(threading)与多进程(multiprocessing )

    进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...

  6. python多线程threading

    本文通过 4个example 介绍python中多线程package —— threading的常用用法, 包括调用多线程, 同步队列类Queue, Ctrl+c结束多线程. example1. 调用 ...

  7. Python:使用threading模块实现多线程编程

    转:http://blog.csdn.net/bravezhe/article/details/8585437 Python:使用threading模块实现多线程编程一[综述] Python这门解释性 ...

  8. python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...

  9. 基于Python的多线程模块Threading小结

    步入正题前,先准备下基本知识,线程与进程的概念. 相信作为一个测试人员,如果从理论概念上来说其两者的概念或者区别,估计只会一脸蒙蔽,这里就举个例子来说明下其中的相关概念. 平安夜刚过,你是吃到了苹果还 ...

随机推荐

  1. java IO之 序列流 集合对象Properties 打印流 流对象

    序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...

  2. SPFA 算法详解

    适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便 派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径 ...

  3. LinkedList源码浅析(jdk1.8)

    LinkedList由双向链表实现的集合,因此可以从头或尾部双向循环遍历. LinkedList的操作都是对双向链表的操作,理解双向链表的数据结构就很容易理解LinkedList的实现. 双向链表由带 ...

  4. [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树

    Problem 普通平衡树 Solution 本题是裸的二叉平衡树.有很多种方法可以实现.这里打的是替罪羊树模板. 此题极其恶心. 前驱后继模块需要利用到rank模块来换一种思路求. 很多细节的地方容 ...

  5. js获取客户端MAC地址

    最近遇到一个需求,医院要求呼叫中心账号必须对应MAC地址,也就是说该MAC地址必须和呼叫中心账号对应才可使用,这可就难道我了,这需求就要求每次都判断用户登录的电脑MAC地址是否有呼叫中心账号,当然只针 ...

  6. C# Web.config配置

    使用 <!--M002 バッチを起動のPath配置--> <add key="BM0002_START_PATH" value="D:\BM0002\B ...

  7. .net 自动摘要等算法 HanLP.net

    参考资料: http://www.hankcs.com/nlp/call-hanlp-in-csharp.html 目前自动摘要算法似乎没有.net 版本,而以java,python 居多 自动摘要算 ...

  8. zTree学习实例

    今天做完一个zTree的实例,供有需要的学习! 效果图如下:

  9. 富文本编辑器UEditor自定义工具栏(一、基础配置与字体、背景色、行间距、超链接实现)

    导读:UEditor 是由百度「FEX前端研发团队」开发的所见即所得富文本web编辑器,功能强大,可定制,是一款优秀的国产在线富文本编辑器,编辑器内可插入图片.音频.视频等. 一.UEditor自定义 ...

  10. DNS,TCP,IP,HTTP,socket,Servlet概念整理

    DNS,TCP,IP,HTTP,socket,Servlet概念整理   常见的协议虽然很容易理解,但是看了之后过一段时间不看还是容易忘,笔记如下,比较零碎,勉强供各位复习.如有错误欢迎指正.   D ...