在发送网络请求的过程中,单个请求的速度总是有着很大的限制,而任务往往需要以更快的速度去执行,这时多线程就是一个很好地选择。python已经给我们封装好了多线程库thread和threading。

thread:比较底层的模块
threading:Higher-level threading interface

ps:建议使用threading模块
- 高级别的threading模块更为先进,对线程的支持更为完善
- 低级别的thread模块同步原语很少
- thread模块对线程什么时候结束完全没有控制,当主线程结束时,所有线程都会强制结束

thread
模块函数

start_new_thread(function, args,kwargs=None): 产生新的线程,args是function的参数,没有时写(),kwargs用来调用这个函数
allocate_lock(): 分配锁,LockType类型
exit(): 让线程退出

LockType的操作

acquire(wait=None):尝试获取锁
locked(): 获取了锁返回True,没有返回False
release():释放锁

Demo1

$ cat t1.py
import thread
from time import sleep

def a():
print "a start"
sleep(2)
print "a end"

def b():
print "b start"
sleep(2)
print "b end"

def main():
thread.start_new_thread(a,())
thread.start_new_thread(b,())
print "all done"

if __name__ == "__main__":
main()

$ python t1.py
all done
b start
a start
最终会发现,每一次运行出来的结果都有可能不同,但是绝对不会出现“a end”和“b end”。这是为什么呢,这里没有写让主线程停下来等所有子线程结束后再继续运行的代码,所以main线程在执行完print "all done"就关闭了a和b两个线程。怎么办呢,可以在这里加一个sleep等待子进程执行完毕后再退出。

Demo2: thread -- 多线程的演示 by sleep

$ cat t2.py
import thread
from time import sleep

def a():
print "a start"
sleep(2)
print "a end"

def b():
print "b start"
sleep(2)
print "b end"

def main():
thread.start_new_thread(a,())
thread.start_new_thread(b,())
sleep (4) ----防止主进程过早退出,加sleep等待子进程执行完毕后再推出
print "all done"

if __name__ == "__main__":
main()
$ python t1.py
b start
a start
a end
b end
all done
但是假设我们不知道子进程执行的时间怎么办,这就是锁的用武之地了。因为使用锁要比使用sleep()函数更为合理。如下所示:

Demo3: thread -- 多线程演示 by lock

实现方式为: 主线程初始化两个锁,分别传给两个函数,两个函数在执行完自己的代码后释放锁,主线程一直在轮询这个锁有没有释放,如果释放了就退出。

def a(lock, nsec):
print "a starting at :", ctime()
sleep(nsec)
lock.release() -- 执行完之后释放锁
print "a end", ctime()

def b(lock, nsec):
print "b starting at :", ctime()
sleep(nsec)
lock.release() -- 执行完之后释放锁
print "b end", ctime()

def main():
print "Demo Starting at:", ctime()

locks = []

# Initialize lock -- 主线程先获取两个锁,占为己有
for i in range(2):
lock = thread.allocate_lock()
lock.acquire()
locks.append(lock)

# 每个进程分配一个锁
thread.start_new_thread(a, (locks[0],2))
thread.start_new_thread(b, (locks[1],4))

for i in range(2): #一直在轮询,看锁有没有释放
while locks[i].locked(): pass

print "all done at:", ctime()
最后的结果为:

$ python thread_demo.py
Demo Starting at: Fri Aug 29 22:03:01 2014
a starting at : Fri Aug 29 22:03:01 2014
b starting at : Fri Aug 29 22:03:01 2014
a end Fri Aug 29 22:03:03 2014
b end Fri Aug 29 22:03:05 2014
all done at: Fri Aug 29 22:03:05 2014
不难发现,thread库的同步机制比较难用,一切都需要主进程来处理。并且没有守护进程,主进程一退,整个世界都会变得很清静。而threading库给我们提供了守护进程。下面就来看看threading的简单用法。

threading
threading提供了Thread类,还提供了很多非常好用的同步机制。感觉重点了解Thread类就可以,多线程,也就是通过Thread类的多个实例。 类的主要方法有:

start():开始线程的执行。thread库里里面,是没有办法控制线程的开始的
join(timeout=None): 等待线程结束,有点类似Demo3中的轮询
run():定义线程的功能

感觉上面是比较重要的,立马就会用到的。还有一些其他的:

getName():获取线程名
setName(name):设置线程名
isAlive(): 返回bool 表示线程是否在运行中
activeCount():返回运行中的线程数
currentThread():返回当前线程对象
enumerate():返回当前活动线程的列表
isDaemon(): 返回线程的Daemon标志
setDaemon(daemonic): 设置线程的Daemon标志,一般在start()函数前调用
settrace(func):为所有线程设置跟踪函数
setprofile(func): 为所有线程设置profile函数

Demo4 -- threading演示

def loop(i, nsec):
print "thread %d starting at : %s" %(i, ctime())
sleep(nsec)
print "thread %d end at : %s" %(i, ctime())

def main():
threads = []
loops = [2, 4]
# 实例化进程
for i in range(len(loops)):
t = threading.Thread(target = loop, args = (i, loops[i]))
threads.append(t)

for i in range(len(loops)):
threads[i].start()

for i in range(len(loops)):
threads[i].join()

print "all done"
最后的结果为:

thread 0 starting at : Sun Aug 31 13:31:28 2014
thread 1 starting at : Sun Aug 31 13:31:28 2014
thread 0 end at : Sun Aug 31 13:31:30 2014
thread 1 end at : Sun Aug 31 13:31:32 2014
all done

对Daemon线程理解:
A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property.
线程可以被标识为"Daemon线程",Daemon线程表明整个Python主程序只有在Daemon子线程运行时可以退出。该属性值继承自父线程,可通过setDaemon()函数设定该值。

Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.
注意:Daemon线程会被粗鲁的直接结束,它所使用的资源(已打开文件、数据库事务等)无法被合理的释放。因此如果需要线程被优雅的结束,请设置为非Daemon线程,并使用合理的信号方法,如事件Event。

Python主程序当且仅当不存在非Daemon线程存活时退出。
即:主程序等待所有非Daemon线程结束后才退出,且退出时会自动结束(很粗鲁的结束)所有Daemon线程。
亦理解为:Daemon设置为子线程是否随主线程一起结束,默认为False。如果要随主线程一起结束需要设置为True。

Daemon线程用途:
Daemons are only useful when the main program is running, and it's okay to kill them off once the other non-daemon threads have exited. Without daemon threads, we have to keep track of them, and tell them to exit, before our program can completely quit. By setting them as daemon threads, we can let them run and forget about them, and when our program quits, any daemon threads are killed automatically.
Daemon线程当且仅当主线程运行时有效,当其他非Daemon线程结束时可自动杀死所有Daemon线程。如果没有Daemon线程的定义,则必须手动的跟踪这些线程,在程序结束前手动结束这些线程。通过设置线程为Daemon线程,则可以放任它们运行,并遗忘它们,当主程序结束时这些Daemon线程将自动被杀死。

转载于:https://www.cnblogs.com/niansi/p/7441582.html

python多线程理解相关推荐

  1. 关于Python多线程的理解

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  2. php和python的多线程,Python多线程以及线程锁简单理解(代码)

    本篇文章给大家带来的内容是关于Python多线程以及线程锁简单理解(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 多线程threading 模块创建线程创建自己的线程类线程通 ...

  3. python多线程有用吗_Python多线程理解

    前言 在写python爬虫的时候遇到了多线程,使用多线程的目的是降低抓取时间.接着我接触了一些IO概念,IO就是Input和Ouput,数据进出CPU的意思. 数据从网线或网卡进入CPU算Input( ...

  4. python 延时_理解Python多线程5:加锁解决问题,但又带来麻烦!

    此系列,已经推送的如下,还没看到的读者,可以走一波: 理解Python多线程4:代码稍作改动,bug就来了 理解Python多线程3:多线程抢夺同一个变量 理解Python多线程2:线程轮询得到CPU ...

  5. python多线程_干货|理解python多线程和多进程

    点击上方"AI遇见机器学习",选择"星标"公众号 原创干货,第一时间送达 一.多线程与多进程 在介绍Python多线程编程之前,先给大家复习一下进程和线程的概念 ...

  6. python 多线程 setdaemon_彻底理解Python多线程中的setDaemon与join配有GIF示意

    在进行Python多线程编程时, join()和 setDaemon()是最常用的方法,下面说说两者的用法和区别. 1.join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.jo ...

  7. python 多线程 setdaemon_彻底理解Python多线程中的setDaemon与join【配有GIF示意】

    在进行Python多线程编程时, join()和 setDaemon()是最常用的方法,下面说说两者的用法和区别. 1.join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.jo ...

  8. Python Web学习笔记之Python多线程基础

    多线程理解 多线程是多个任务同时运行的一种方式.比如一个循环中,每个循环看做一个任务,我们希望第一次循环运行还没结束时,就可以开始第二次循环,用这种方式来节省时间. python中这种同时运行的目的是 ...

  9. c++主线程等待子线程结束_简单明了的 Python 多线程来了 | 原力计划

    作者 | 万里羊责编 | 王晓曼出品 | CSDN博客线程和进程计算机的核心是CPU,它承担了所有的计算任务,就像是一座工厂在时刻运行.如果工厂的资源有限,一次只能供一个车间来使用,也就是说当一个车间 ...

最新文章

  1. NPM 3 Beta为Windows用户带来利好消息
  2. cad文本改宋体字型lisp_CAD的40个常用命令和20个常见问题解决方法 撩妹必备技能...
  3. Mysql函数示例(如何定义输入变量与返回值)
  4. jquery与json的结合
  5. 【Interfacenavigation】按钮(29)
  6. nginx+apache实现负载均衡+动静分离配置(编译安装)
  7. 关于数论【莫比乌斯反演】
  8. 深入浅出通信原理MIMO合集
  9. 信息论 基础知识(一)
  10. Boss直聘招聘数据分析-202104月版
  11. ps如何用创建和使用动作
  12. 计算机基础——Word 2010
  13. 左霆:无处不在的订阅经济
  14. 分布式共识算法丨Raft丨Raft-Extended 论文翻译
  15. python蚂蚁森林自动偷能量_蚂蚁森林自动偷能量 激活 - 『精品软件区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn...
  16. 单场淘汰制场次计算方法_体育编排
  17. Intellij IDEA神器那些让人爱不释手的小技巧
  18. CCNP精粹系列之二十九--发布bgp子网信息,推荐
  19. 程序员笔试题---国信证券
  20. 常用电脑检测软件列表!提供下载!

热门文章

  1. 如何在redhat8里使用gcc命令_如何使用DISM命令行工具修复Windows 10映像
  2. 软件加入使用时间_有了抢口罩软件,电商也进行了升级,我们又有了新软件
  3. Loadrunner-web资源相关图表
  4. python全局变量的声明和使用_Python二级(07)——函数和代码复用
  5. python求两数之和的命令_python实现读取命令行参数的方法
  6. 跳跃游戏Python解法
  7. boost库 python_Boost.Python简介-阿里云开发者社区
  8. python骂人的程序_Python实现敏感词过滤的4种方法
  9. redhat7.1安装mysql_redhat7.1 安装mysql 5.7.10步骤详解(图文详解)
  10. 元件又焊反了,电路板又在冒烟了!