Python的多线程实现

参考:

1.
使用Python进行线程编程:http://www.ibm.com/developerworks/cn/aix/library/au-threadingpython/

2.
Python:使用threading模块实现多线程编程:http://blog.csdn.net/bravezhe/article/details/8585437

3.
Python并行任务技巧:http://www.oschina.net/translate/python-parallelism-in-one-line

概述

Python虚拟机使用GIL(Global Interpreter
Lock,全局解释器锁)来实现互斥线程对共享资源的访问,暂时无法利用多处理器的优势。

Python中,thread和threading均支持多线程,threading是对thread的封装与升级,一般使用threading模块,在具体实现中,一般结合队列Queue(线程安全)使用,实现多个线程之间的同步。

多线程的一些基本概念:

对象互斥锁:用来保证共享数据的操作的完整性,即任何时刻,只能有一个线程访问该对象。Python中使用threading模块提供的Lock类,争夺资源时,首先acquire(),使用完成中release()释放。

死锁与可重入锁:对象互斥锁实现了简单的公共资源的保护,但是实际应用中,如果有多个公共资源,在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会出现死锁。所谓死锁:
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
这种情况下Python使用可重入锁threading.RLock实现,RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。

常用的多线程的实现模式

1. threading+队列

当多个线程需要共享数据或者资源的时候,可能会使得线程的使用变得复杂。线程模块提供了许多同步原语,包括信号量、条件变量、事件和锁。当这些选项存在时,最佳实践是转而关注于使用队列。相比较而言,队列更容易处理,并且可以使得线程编程更加安全,因为它们能够有效地传送单个线程对资源的所有访问,并支持更加清晰的、可读性更强的设计模式。

参考1的例3和例4分别演示了使用单个队列和多个队列实现多线程,具有较高的使用性。

参考3的引例1和引例2演示了生产者/消费者模式、以及简单线程池的实现。

2. Map的并发实现。

这种方式直接使用multiprocessing.dummy
中封装的现成的Pool,写好具体的业务处理函数,只需短短四行代码即可实现多线程,并且可以利用多处理器提高效率。

参见参考3中的例子。

3. 多线程的封装

待实现

时间: 2024-10-16 18:56:57

Python的多线程实现的相关文章

Python实现多线程HTTP下载器

本文将介绍使用Python编写多线程HTTP下载器,并生成.exe可执行文件. 环境:windows/Linux + Python2.7.x 单线程 在介绍多线程之前首先介绍单线程.编写单线程的思路为: 解析url: 连接web服务器: 构造http请求包: 下载文件. 接下来通过代码进行说明. 解析url 通过用户输入url进行解析.如果解析的路径为空,则赋值为'/':如果端口号为空,则赋值为"80":下载文件的文件名可根据用户的意愿进行更改(输入'y'表示更改,输入其它表示不需要更

python的多线程到底有没有用?

在群里经常听到这样的争执,有人是虚心请教问题,有人就大放厥词因为这个说python辣鸡.而争论的核心无非就是,python的多线程在同一时刻只会有一条线程跑在CPU里面,其他线程都在睡觉.这是真的吗? 是真的.这个就是因为传说中的GIL(全局解释锁)的存在.不明白这个词的可以去百度一下,我解释不好(大家都是程序猿你懂的,我写错一个词就要挨喷了,就算我没写错对方理解错了,我也一样要挨喷).有了这样一个看似bug的存在,就导致了上面说的情况:同一时刻内,python的线程只有一条在CPU里面运行.

python之多线程

声明:示例来源<python核心编程> 前言 单线程处理多个外部输入源的任务只能使用I/O多路复用,如:select,poll,epoll. 特别值得注意的是:由于一个串行程序需要从每个 I/O 终端通道来检查用户的输入,程序在读取 I/O 终端通道时不能阻塞,因为用户输入的到达时间是不确定的,并且阻塞会妨碍其他 I/O 通道的处理. select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责

Python的多线程和多进程模块对比测试

本文主要对比测试Python的多线程和多进程模块在CPU类型和I/O的任务操作时的效率 一 测试CPU消耗类型任务 在一台多核CPU的服务器上执行多线程代码,理论上代码执行时会利用多余的CPU核心来提升性能.但是由于Python的GIL的存在,使用多线程来执行CPU繁重的任务,未必能得到性能提升.但是GIL又必不可少,因为在Python解释器中执行线程是不安全的,也就是说为了保证Python线程执行时的安全,Python提供了一个全局锁,同一时刻,只允许一个线程获得这个全解锁并执行. CPU消耗

自动化测试框架解析2-----关于python的多线程问题

在阅读代码的时候,碰到了python中多线程的问题.在这里做一个记录 mport time  import threading def movie(func): for i in range(2): print "I am watching movie <%s>, time:%s"%(func,time.ctime()) time.sleep(5) def music(func): for i in range(2): print "I am listennig 

Python threading多线程编程示例

Python 的多线程有两种实现方法: 函数,线程类 1.函数 调用 thread 模块中的 start_new_thread() 函数来创建线程,以线程函数的形式告诉线程该做什么 # -*- coding: utf-8 -*- import thread def f(name): #定义线程函数 print "this is " + name if __name__ == '__main__': thread.start_new_thread(f, ("thread1&qu

【python】多线程编程

使用多线程编程和一个共享的数据结构如queue,这种程序任务可以用多个功能单一的线程来组织: UserRequestThread:负责读取客户的输入,可能是一个I/O信道.程序可能创建多个线程,每个客户一个,请求会被放入队列中 RequestProcessor:一个负责从队列中获取并处理请求的线程,它为下面那种线程提供输出 ReplyThread:负责把给用户的输出取出来,如果是网络应用程序就把结果发送出去,否则就保存到本地文件系统或数据库中. 一个顺序执行单线程的例子: from time i

python中多线程调度机制以及GIL

总结下python中线程调度机制. 对于线程调度机制而言,同操作系统的进程调度一样,最关键是要解决两个问题: 1.在何时选择挂起当前线程,并选择处于等待的先一个线程呢? 2.在众多等待的线程中,选择哪一个作为激活线程呢? 在python多线程机制中,这个两个问题是有两个层次解决的. 如,进程间的切换,当发生了时钟中断,操作系统响应时钟中断,并在这个时候开始进程的调度. 同样的,python也是通过软件模拟了这样的时钟中断,来激激活线程的调度. 我们知道,python字节码解释器是按照指令,顺序一

[ Python - 11 ] 多线程及GIL全局锁

1. GIL是什么? 首先需要明确的一点是GIL并不是python的特性, 它是在实现python解析器(Cpython)时所引入的一个概念. 而Cpython是大部分环境下默认的python执行环境,要明确一点:GIL并不是python的特性,python完全可以不依赖于GIL. 2. 为什么会有GIL? 为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程间数据的一致性和状态同步的完整性 (例如:线程2需要线程1执行完成的结果,然而线程2又比线程1代码量少,线程2

python里多线程的写法

python里多线程的写法 今天用到python多线程的时候, 发现不知道如何正确的等待所有线程结束后再结束主线程. 其实到最后我才知道这都是杞人忧天, Thread()出来的实例本来就是等到主进程结束后才结束. 官方解释: daemon A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called