Python中的多进程与多线程(二)
在上一章中,学习了Python多进程编程的一些基本方法:使用跨平台多进程模块multiprocessing提供的Process、Pool、Queue、Lock、Pipe等类,实现子进程创建、进程池(批量创建子进程并管理子进程数量上限)以及进程间通信。这一章学习下Python下的多线程编程方法。
一、threading
线程是操作系统执行任务的最小单元。Python标准库中提供了threading模块,对多线程编程提供了很便捷的支持。
下面是使用threading实现多线程的代码:
#!/usr/bin/python
# -*- coding: utf-8 -*
__author__ = 'zni.feng'
import sys
reload (sys)
sys.setdefaultencoding('utf-8') import threading, time def test(index):
print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print 'thread %s starts.' % threading.current_thread().name
print 'the index is %d' % index
time.sleep(3)
print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print 'thread %s ends.' % threading.current_thread().name if __name__ == "__main__":
print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print 'thread %s starts.' % threading.current_thread().name
#创建线程
my_thread = threading.Thread(target = test, args=(1,) , name= 'zni_feng_thread')
#等待2s
time.sleep(2)
#启动线程
my_thread.start()
#等待线程结束
my_thread.join()
print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print 'thread %s ends.' % threading.current_thread().name
输出结果为:
2017-01-12 22:06:32
thread MainThread starts.
2017-01-12 22:06:34
thread zni_feng_thread starts.
the index is 1
2017-01-12 22:06:37
thread zni_feng_thread ends.
2017-01-12 22:06:37
thread MainThread ends.
[Finished in 5.1s]
其中,threading模块的current_thread()函数会返回当前线程的实例。
二、Lock
多进程与多线程的最大不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响。而多线程中,所有变量都由所有线程共享,所以,任何一个共享变量都可以被任何一个线程修改。因此线程之间共享数据最大的危险在于多个线程同时改变一个变量。为了解决这个问题,我们可以借助于threading模块的Lock类给共享变量加锁。
先看看使用多线程写同一个共享变量,不加锁的例子:
#!/usr/bin/python
# -*- coding: utf-8 -*
__author__ = 'zni.feng'
import sys
reload (sys)
sys.setdefaultencoding('utf-8')
import threading class Account:
def __init__(self):
self.balance = 0 def add(self):
for i in range(0,100000):
self.balance += 1 def delete(self):
for i in range(0,100000):
self.balance -=1 if __name__ == "__main__":
account = Account()
#创建线程
thread_add = threading.Thread(target=account.add, name= 'Add')
thread_delete = threading.Thread(target=account.delete, name= 'Delete') #启动线程
thread_add.start()
thread_delete.start() #等待线程结束
thread_add.join()
thread_delete.join() print 'The final balance is: ' + str(account.balance)
运行结果为:
The final balance is: -51713
[Finished in 0.1s]
可以发现,每次运行,它的最终结果都会不同,而且都不是0。就是因为不同线程在同时修改同一个变量时,发生了冲突,某些中间变量没有按顺序被使用导致。
现在我们使用Lock对程序进行加锁:
#!/usr/bin/python
# -*- coding: utf-8 -*
__author__ = 'zni.feng'
import sys
reload (sys)
sys.setdefaultencoding('utf-8')
import threading class Account:
def __init__(self):
self.balance = 0 def add(self, lock):
#获得锁
lock.acquire()
for i in range(0,100000):
self.balance += 1
#释放锁
lock.release() def delete(self, lock):
#获得锁
lock.acquire()
for i in range(0,100000):
self.balance -=1
#释放锁
lock.release() if __name__ == "__main__":
account = Account()
lock = threading.Lock()
#创建线程
thread_add = threading.Thread(target=account.add, args=(lock, ), name= 'Add')
thread_delete = threading.Thread(target=account.delete, args=(lock, ), name= 'Delete') #启动线程
thread_add.start()
thread_delete.start() #等待线程结束
thread_add.join()
thread_delete.join() print 'The final balance is: ' + str(account.balance)
可以发现,无论如何执行多少次,balance结果都为0。如果将每次balance计算的结果都打印出来,还会发现,当一个线程开始执行时,另一个线程一定会等到前一个线程执行完(准确地说是lock.release()执行完)后才开始执行。
The final balance is: 0
[Finished in 0.1s]
Python中的多进程与多线程(二)的更多相关文章
- python中的多进程与多线程(二)
1.使用多线程可以有效利用CPU资源,线程享有相同的地址空间和内存,这些线程如果同时读写变量,导致互相干扰,就会产生并发问题,为了避免并发问题,绝不能让多个线程读取或写入相同的变量,因此python中 ...
- 深入浅析python中的多进程、多线程、协程
深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...
- 聊聊Python中的多进程和多线程
今天,想谈一下Python中的进程和线程. 最近在学习Django的时候,涉及到了多进程和多线程的知识点,所以想着一下把Python中的这块知识进行总结,所以系统地学习了一遍,将知识梳理如下. 1. ...
- 学习笔记--python中使用多进程、多线程加速文本预处理
一.任务描述 最近尝试自行构建skip-gram模型训练word2vec词向量表.其中有一步需要统计各词汇的出现频率,截取出现频率最高的10000个词汇进行保留,形成常用词词典.对于这个问题,我建立了 ...
- Python中的多进程、多线程和协程
本文中的内容来自我的笔记.撰写过程中参考了胡俊峰老师<Python程序设计与数据科学导论>课程的内容. 并发处理:多进程和多线程 前置 概念: 并发:一段时间内同时推进多个任务,但不一定要 ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- Python中的多进程与多线程/分布式该如何使用
在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程程序同时 ...
- python中的多进程与多线程(一)
进程是一个执行中的程序,每个进程有自己的地址空间.内存.数据栈以及其他用于跟踪执行的辅助数据.操作系统管理其上所有进程,并合理分配时间. 进程也可以通过fork或spawn派生新的进程,每个新进程有自 ...
- Python中使用多进程来实现并行处理的方法小结
进程和线程是计算机软件领域里很重要的概念,进程和线程有区别,也有着密切的联系,先来辨析一下这两个概念: 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和 ...
随机推荐
- java利用poi导出数据到excel
背景: 上一篇写到利用jtds连接数据库获取对应的数据,本篇写怎样用poi将数据到处到excel中,此程序为Application 正文: 第三方poi jar包:poi驱动包下载 代码片段: /** ...
- knob.js进度插件
关于knob.js进度插件的使用 关于这个插件,妹的,第一次使用坑死爹了,各种不会,幸亏我有持之以恒的精神,最终还是让其臣服于我的胯下.... 1. 引入 head 部分添加knob.js,同时引 ...
- ReSharper 8.1支持TypeScript语言之代码检查特征
自ReSharper 8.1发布以来,就支持TypeScript.其在TypeScript语言拼写帮助和代码完成中,几乎是一个里程碑的发展,这是令人激动的改进. 支持TypeScript效果就目前测试 ...
- Ubuntu12.04环境搭建遇到的问题和建议(一个)
后的新公司需要在Ubuntu12.04在结构Android开发环境,在这个过程中,我们还是会遇到很多问题,这里记录.为了方便自己的未来,有人谁需要参考.从网络! 1. Q:在终端: sudo apt- ...
- Mysql插入内容过长(Packet for query is too large)
原文:Mysql插入内容过长(Packet for query is too large) 这个以前一直没有碰到过,一次性向Mysql数据库插入内容过长的话会出现这个问题,解决办法就是在Mysql配置 ...
- Android项目---LayoutParams
LinearLayout.LayoutParams extends ViewGroup.MarginLayoutParams java.lang.Object ↳ android.view.Vi ...
- rsync服务器
转自:http://www.mike.org.cn/blog/index.php?load=read&id=639###pp=0 [rsync实现网站的备份,文件的同步,不同系统的文件的同步, ...
- ASP.NET MVC 缓存扩展 - Donut Caching
项目介绍 ASP.NET MVC Extensible Donut Caching brings donut caching to ASP.NET MVC 3 and later. The code ...
- 使用shell+awk完成Hive查询结果格式化输出
好久不写,一方面是工作原因,有些东西没发直接发,另外的也是习惯给丢了,内因所致.今天是个好日子,走起! btw,实际上这种格式化输出应该不只限于某一种需求,差不多是通用的. 需求: --基本的:当前H ...
- keepalive学习
keepalive学习之软件设计 软件架构如下图所示: Keepalived 完全使用标准的ANSI/ISO C写出. 该软件主要围绕一个中央I/O复用分发器而设计,这个I/O复用分发器提供网络实时功 ...