python之多线程

python之多线程声明:示例来源《python核心编程》前言单线程处理多个外部输入源的任务只能使用I/O多路复用,如:select,poll,epoll。特别值得注意的是:由于一个串行程序需要从每个I/O终端

大家好,又见面了,我是你们的朋友全栈君。

声明:示例来源《python核心编程》

前言

  单线程处理多个外部输入源的任务只能使用I/O多路复用,如:select,poll,epoll。

  特别值得注意的是:由于一个串行程序需要从每个 I/O 终端通道来检查用户的输入,程序在读取 I/O 终端通道时不能阻塞,因为用户输入的到达时间是不确定的,并且阻塞会妨碍其他 I/O 通道的处理。

  select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现只负责把数据从内核拷贝到用户空间。

为此就引出了我们的主体多线程,多线程的特点:

  1. 本质上是异步的
  2. 需要多个并发活动
  3. 每个活动的处理顺序可能是不确定的,或者说是随机的、不可预测的。

什么是进程?
进程就是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理地分配时间。进程也可以通过派生( fork 或 spawn)新的进程来执行其他任务,不过因为每个新进程也都拥有自己的内存和数据栈等,所以只能采用进程间通信( IPC)的方式共享信息。

什么是线程?
线程(有时候称为轻量级进程)与进程类似,不过它们是在同一个进程下执行的,并共享相同的上下文。可以将它们认为是在一个主进程或“主线程”中并行运行的一些“迷你进程”。

python中的多线程实现

threading模块中的对象列表

<span role="heading" aria-level="2">python之多线程

ps:我们通过python实现多线程编程,主要用到的是threading.Thread对象

Thread对象常用属性和方法

<span role="heading" aria-level="2">python之多线程

<span role="heading" aria-level="2">python之多线程

多线程示例

context: python2.7.13

python通过Thread对象创建一个多线程实例,主要有3种方式:

  1. 创建 Thread 的实例,传给它一个函数。
  2. 创建 Thread 的实例,传给它一个可调用的类实例。
  3. 派生 Thread 的子类,并创建子类的实例。

ps:我们通常会选择第一个或第三个方案。当你需要一个更加符合面向对象的接口时,会选择后者。所以,建议使用第三种方案,它是最适合你的应用和未来扩展的方法

示例1:创建 Thread 的实例,传给它一个函数。

 1 #!/usr/bin/env python
 2 #-*- coding:utf-8 -*-
 3 import threading
 4 from time import sleep,ctime
 5 
 6 loops = [4,2]
 7 
 8 def loop(nloop,nsec):
 9     print "start loop",nloop,"at:",ctime()
10     sleep(nsec)
11     print "loop",nloop,'done at:',ctime()
12 
13 def main():
14     print "Starting at:",ctime()
15     threads = []
16     nloops = range(len(loops))
17     #完成所有线程分配,并不立即开始执行
18     for i in nloops:
19         t = threading.Thread(target=loop,args=(i,loops[i]))
20         threads.append(t)
21     #开始调用start方法,同时开始所有线程
22     for i in nloops:
23         threads[i].start()
24     #join方法:主线程等待所有子线程执行完成,再执行主线程接下来的操作。
25     for i in nloops:
26         threads[i].join()
27 
28     print "All done at:",ctime()
29 if __name__=="__main__":
30     main()
<span role="heading" aria-level="2">python之多线程
<span role="heading" aria-level="2">python之多线程

Starting at: Sun Jun 18 10:00:49 2017
start loop 0 at: Sun Jun 18 10:00:49 2017
start loop 1 at: Sun Jun 18 10:00:49 2017
loop 1 done at: Sun Jun 18 10:00:51 2017
loop 0 done at: Sun Jun 18 10:00:53 2017
All done at: Sun Jun 18 10:00:53 2017

Process finished with exit code 0

resault

示例2:创建 Thread 的实例,传给它一个可调用的类实例

<span role="heading" aria-level="2">python之多线程
<span role="heading" aria-level="2">python之多线程

#!/usr/bin/env python
#-*- encoding:utf-8 -*-
import threading
from time import sleep,ctime

loops = [4,2]
class ThreadFunc(object):
    def __init__(self,func,args,name=""):
        self.name = name
        self.func = func
        self.args = args
    #使类具有函数行为,就像函数的代理(proxy)
    def __call__(self):
        self.func(*self.args)

def loop(nloop,nsec):
    print "start loop",nloop,"at:",ctime()
    sleep(nsec)
    print "loop",nloop,'done at:',ctime()

def main():
    print "Starting at:",ctime()
    threads = []
    nloops = range(len(loops))
    #完成所有线程分配,并不立即开始执行
    for i in nloops:
        t = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
        threads.append(t)
    #开始调用start方法,同时开始所有线程
    for i in nloops:
        threads[i].start()
    #join方法等待子线程执行完成,再执行主线程接下来的操作。
    for i in nloops:
        threads[i].join()

    print "All done at:",ctime()
if __name__=="__main__":
    main()

传入类实例

<span role="heading" aria-level="2">python之多线程
<span role="heading" aria-level="2">python之多线程

Starting at: Sun Jun 18 10:03:52 2017
start loop 0 at: Sun Jun 18 10:03:52 2017
start loop 1 at: Sun Jun 18 10:03:52 2017
loop 1 done at: Sun Jun 18 10:03:54 2017
loop 0 done at: Sun Jun 18 10:03:56 2017
All done at: Sun Jun 18 10:03:56 2017

Process finished with exit code 0

resault

示例3:派生 Thread 的子类,并创建子类的实例。

自定义类MyThread

  1. 文件名:mythread.py,
  2. 内容:MyThread为threading.Thread的派生类
#!/usr/bin/env python#-*- coding:utf-8 -*-import threadingfrom time import sleep,ctimeclass MyThread(threading.Thread):    def __init__(self,func,args,name=""):        threading.Thread.__init__(self)        self.name = name        self.func = func        self.args = args    def get_res(self):        return self.res    def run(self):        print "Starting",self.name,"at:",ctime()        self.res = self.func(*self.args)        print self.name,"finish at:",ctime()

菲波那切数列,阶乘,累加单线程也多线程对比

#!/usr/bin/env python#-*- coding:utf-8 -*-#MyThread为自定义的threading.Thread的派生类from mythread import MyThreadfrom time import sleep,ctime#斐波那契数列def fib(x):    sleep(0.005)    if x < 2:return 1    return (fib(x-2)+fib(x-1))#阶乘def fac(x):    sleep(0.1)    if x < 2:return 1    return (x*fac(x-1))#累加def sum(x):    sleep(0.1)    if x < 2:return 1    return (x + sum(x-1))funcs = [fib,fac,sum]n = 12def main():    nfuncs = range(len(funcs))    print "---SINGLE THREAD---"    for i in nfuncs:        print "Starting",funcs[i].__name__,"at:",ctime()        print funcs[i](n)        print funcs[i].__name__,"finish at:",ctime()    print "\n---MULTIPLE THREADS---"    threads = []    for i in nfuncs:        t = MyThread(funcs[i],(n,),funcs[i].__name__)        threads.append(t)    for i in nfuncs:        threads[i].start()    for i in nfuncs:        threads[i].join()        print threads[i].get_res()    print "All Done!"if __name__ == '__main__':    main()
<span role="heading" aria-level="2">python之多线程
<span role="heading" aria-level="2">python之多线程

---SINGLE THREAD---
Starting fib at: Sun Jun 18 09:12:17 2017
233
fib finish at: Sun Jun 18 09:12:24 2017
Starting fac at: Sun Jun 18 09:12:24 2017
479001600
fac finish at: Sun Jun 18 09:12:26 2017
Starting sum at: Sun Jun 18 09:12:26 2017
78
sum finish at: Sun Jun 18 09:12:27 2017

---MULTIPLE THREADS---
Starting fib at: Sun Jun 18 09:12:27 2017
Starting fac at: Sun Jun 18 09:12:27 2017
Starting sum at: Sun Jun 18 09:12:27 2017
fac finish at: Sun Jun 18 09:12:28 2017
sum finish at: Sun Jun 18 09:12:28 2017
fib finish at: Sun Jun 18 09:12:34 2017
233
479001600
78
All Done!

Process finished with exit code 0

resault

  以单线程模式运行时,只是简单地依次调用每个函数,并在函数执行结束后立即显示相应的结果。

  而以多线程模式运行时,并不会立即显示结果。 因为我们希望让 MyThread 类越通用越好(有输出和没有输出的调用都能够执行),我们要一直等到所有线程都执行结束,然后调用get_res()方法来最终显示每个函数的返回值。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155868.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 电脑爱好者——投稿与稿费指南

    电脑爱好者——投稿与稿费指南一、稿件投到哪里?请参照期刊最近一期中各栏目每页页眉上的投稿信箱或责编信箱。投稿信箱依此为准,杂志上的责编信箱是法定的投稿信箱,稿件一定要根据内容,投对栏目。二、投稿格式如何?正文用TXT格式,若有图片须标明图号。图片直接抓为无损的BMP格式或高画质JPG格式并打包压缩为ZIP作为附件发送。无论新老作者,稿件正文末尾均要注明作者详细联系信息和通讯地址。三、稿费标准如何?稿费一般

    2022年6月12日
    57
  • Qt面试题整理

    Qt面试题整理1、Qt信号槽机制的优势(1)类型安全。需要关联的信号和槽的签名必须是等同的,即信号的参数类型和参数个数同接收该信号的槽的参数类型和参数个数相同。不过,一个槽的参数个数是可以少于信号的参数个数的,但缺少的参数必须是信号参数的最后一个或几个参数。如果信号和槽的签名不符,编译器就会报错。(2)松散耦合。信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无需知道是哪个对象的哪个槽需要接收它发出的…

    2022年6月25日
    96
  • 二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#[通俗易懂]

    设计模式-谈谈模式和设计模式模式(Pattern),指事物的标准样式,百度百科上面说的,其实说白了模式就是我们现在说的套路!模式 == 套路模式是一种思想,说大了特别的复杂和深奥,不管怎么样模式的使用可以解决特定场景下特定的问题!准确表达:模式是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案。软件模式那么在软件中使用模式,就是软件模式(Sof…

    2022年2月27日
    49
  • pycharm企业版激活码-激活码分享[通俗易懂]

    (pycharm企业版激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsa…

    2022年3月21日
    203
  • css 文字两端对齐

    css 文字两端对齐

    2021年7月3日
    86
  • 编程中的卫语句

    什么是卫语句在《阿里巴巴Java开发手册》中提到,多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。那么,什么是卫语句呢?在中文维基百科中是这样介绍的在计算机程序设计中,卫(guard)是布尔表达式,其结果必须为真,程序才能执行下去。卫语句(guardcode或guardclause)用于检查先决条件。卫语句的用途,例如:引用(reference)使用前检查是否为空引用;处置模式使用一个布尔域,使得释放资源操作成为幂等运算,即多次释放资源等效于只释放一次。卫语句可用于子进程的提前

    2022年4月7日
    334

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号