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.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和 ...
随机推荐
- A在SP.NET跨页多选
在ASP.NET跨页多选 本文介绍怎样在ASP.NET中实现多页面选择的问题.其详细思路非常easy:用隐藏的INPUT记住每次选择的项目,在进行数据绑定时.检查保存的值,再在DataGrid中进行选 ...
- SQL点滴17—使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识
原文:SQL点滴17-使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识 在开发过程中会遇到需要弄清楚这个数据库什么时候建的,这个数据库中有多少表,这个存储过程长的什么样子等等信息 ...
- 使用Windows2003创建DNS服务器 - 进阶者系列 - 学习者系列文章
Windows 2003的DNS服务器的配置还是比较简单的.下面简要介绍下DNS服务器的配置. 1. 打开控制面板,选择 添加删除Windows组件,选择 网络服务 ,选择 详细信息,选择 域名 ...
- Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
功能:在textbox中输入内容,动态从数据库模糊查询显示到下拉框中,以供选择 1.建立一aspx页面,html代码 <HTML> <HEAD> <title>We ...
- MVC无刷新分页
MVC无刷新分页(即局部刷新,带搜索,页数选择,排序功能) 我查看了很多网站,大部分评论分页都是局部刷新的,可大部分电商商品展示分页都是有刷新页面的,于是我便做了一个商品展示无刷新分页的例子.接下 ...
- 31、Thinking in Java
- [转载]Android中WebView自适应屏幕
webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomControls(false); //隐藏webview缩放按钮 让Webview加载的页面居中显示有我知道的 ...
- 24个JavaScript初学者最佳实践
这里面说到的一个就是使用循环新建一个字符串时,用到了join(),这个比较高效,常常会随着push(); 绑定某个动作时,可以把要执行的绑定内容定义为一个函数,然后再执行.这样做的好处有很多.第一是可 ...
- wcf契约随记
1.wcf契约分为:服务契约,操作契约,消息契约.数据契约 -------------------服务契约: [ServiceContract( Name = "name_IUser&quo ...
- ShopEx4.8.5.55328破解版
ShopEx4.8.5.55328最新版完美破解版 http://club.1688.com/article/30369057.html?domainid=lhy16868 ShopEx4.8.5.5 ...