python 多线程编程之_thread模块
参考书籍:python核心编程
_thread模块除了可以派生线程外,还提供了基本的同步数据结构,又称为锁对象(lock object,也叫原语锁、简单锁、互斥锁、互斥和二进制信号量)。
下面是常用的线程函数:
| 函数 | 描述 |
| start_new_thread(function,args,kwargs=None) | 派生一个新的线程,使用给定的args和可选的kwargs来执行function |
| allocate_lock() | 分配LockType对象 |
| exit() | 退出线程指令 |
| LockType锁对象的方法 | |
| acquire(wait=None) | 尝试获取锁对象 |
| locked() | 如果获取了锁对象则返回True,否则返回False |
| release() | 释放锁 |
_thread模块的核心函数是start_new_thread()。专门用来派生新的线程。
我们对上节文章的onethr.py文件稍作修改:
#!/usr/bin/env python import _thread
from time import sleep,ctime def loop0():
print('开始循环0次在:',ctime())
sleep(4)
print('结束循环0次在:',ctime()) def loop1():
print('开始循环1次在:',ctime())
sleep(2)
print('结束循环1次在:',ctime()) '''
def main():
print('开始于:',ctime())
loop0()
loop1()
print('所有的任务都完成于:',ctime())
''' def main():
print('starting at:', ctime())
_thread.start_new_thread(loop0, ())
_thread.start_new_thread(loop1, ())
sleep(6)
print('all done at:', ctime()) if __name__ =='__main__':
main(
执行该脚本三遍,结果:
PS C:\Users\WC> python E:\Python3.6.3\workspace\mtsleepA.py
starting at: Mon Mar 26 21:56:10 2018
开始循环1次在: Mon Mar 26 21:56:10 2018
开始循环0次在: Mon Mar 26 21:56:10 2018
结束循环1次在: Mon Mar 26 21:56:12 2018
结束循环0次在: Mon Mar 26 21:56:14 2018
all done at: Mon Mar 26 21:56:16 2018
PS C:\Users\WC> python E:\Python3.6.3\workspace\mtsleepA.py
starting at: Mon Mar 26 22:00:43 2018
开始循环0次在: Mon Mar 26 22:00:43 2018
开始循环1次在: Mon Mar 26 22:00:43 2018
结束循环1次在: Mon Mar 26 22:00:45 2018
结束循环0次在: Mon Mar 26 22:00:47 2018
all done at: Mon Mar 26 22:00:49 2018
PS C:\Users\WC> python E:\Python3.6.3\workspace\mtsleepA.py
starting at: Mon Mar 26 22:00:56 2018
开始循环0次在: Mon Mar 26 22:00:56 2018
开始循环1次在: Mon Mar 26 22:00:56 2018
结束循环1次在: Mon Mar 26 22:00:58 2018
结束循环0次在: Mon Mar 26 22:01:00 2018
all done at: Mon Mar 26 22:01:02 2018
由上面的代码可知,start_new_thread()必须包含两个参数,即使要执行的函数不需要参数,也要传递一个空元组。
我们注意到:loop0还是loop1开始的顺序竟然可以是无序的;loop0和loop1是同时执行的;loop1是在loop0之前结束的;整个程序一共耗时6秒。
我们可以说,loop0和loop1是并发执行的。
我们在主程序(其实也就是主线程)中增加了一个sleep(6)的语句,这其实是为了避免主程序结束的时候,loop0和loop1两个线程还没有结束的问题。这也是_thread模块的一种线程同步机制。
但是,我们要说这样使用sleep()来进行线程同步是不靠谱的,这也是_thread的一个弊端所在。
这时,我们可以引用锁机制来实现相应的线程管理,并且同时改善单独的循环函数实现方式:
import _thread
from time import sleep, ctime
#不再把4秒和2秒硬性的编码到不同的函数中,而是使用唯一的loop()函数,并把这些常量放进列表loops中
loops=[4,2]
#代替了之前的loop*()函数,三个参数分别代表了处于第几个循环中,睡眠时间和锁对象。每个循环执行到最后一句的时候,释放锁对象,告诉主线程该线程已完成
def loop(nloop,sec,lock):
print('开始循环',nloop,'在:',ctime())
sleep(sec)
print('循环',nloop ,'结束于:',ctime())
lock.release() def main():
print('开始于:',ctime())
locks=[]
nloops=range(len(loops)) #第一个for循环中,创建了一个锁的列表,通过thread.allocate_lock()方法得到锁对象,再通过acquire()方法取到锁(相当于把锁锁上),取到之后就可以把它添加到锁列表locks中。
for i in nloops:
lock=_thread.allocate_lock()
lock.acquire()
locks.append(lock)
#第二个for循环中,主要用于派生线程。每个线程都会调用loop()函数,并传递循环号、睡眠时间以及用于该线程的锁。
for i in nloops:
_thread.start_new_thread(loop,(i,loops[i],locks[i]))
#第三个for循环,按照顺序检查每个锁。每个线程执行完毕后,都会释放自己的锁对象。这里使用忙等待,让主线程等所有的锁都释放后才继续执行
for i in nloops:
while locks[i].locked():
pass
print('所有的任务完成于:',ctime()) if __name__ =='__main__':
main()
执行结果:
开始循环 1 在: Mon Mar 26 22:49:25 2018
开始循环 0 在: Mon Mar 26 22:49:25 2018
循环 1 结束于: Mon Mar 26 22:49:27 2018
循环 0 结束于: Mon Mar 26 22:49:29 2018
所有的任务完成于: Mon Mar 26 22:49:29 2018
上述结果除了表名两次循环是并发执行的之外,整个程序一共用时4秒,而不是之前的6秒。
python 多线程编程之_thread模块的更多相关文章
- python 多线程编程之threading模块(Thread类)创建线程的三种方法
摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...
- python并发编程之asyncio协程(三)
协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...
- python并发编程之threading线程(一)
进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...
- Python 多进程编程之multiprocessing--Process
Python 多进程编程之multiprocessing 1,Process 跨平台的进程创建模块(multiprocessing), 支持跨平台:windowx/linux 创建和启动 创 ...
- python并发编程之Queue线程、进程、协程通信(五)
单线程.多线程之间.进程之间.协程之间很多时候需要协同完成工作,这个时候它们需要进行通讯.或者说为了解耦,普遍采用Queue,生产消费模式. 系列文章 python并发编程之threading线程(一 ...
- python并发编程之gevent协程(四)
协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...
- python并发编程之multiprocessing进程(二)
python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. 系列文章 python并发编程之threading线程(一) python并 ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- iOS多线程编程之NSThread的使用
目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ...
随机推荐
- Aso.Net Core 的配置系统Configuration
目录 Aso.Net Core 的配置系统Configuration 01.Json文件的弱类型方式读取 02.Json文件的强类型获取方式 Aso.Net Core 的配置系统Configurati ...
- 深度学习解决NLP问题:语义相似度计算
在NLP领域,语义相似度的计算一直是个难题:搜索场景下query和Doc的语义相似度.feeds场景下Doc和Doc的语义相似度.机器翻译场景下A句子和B句子的语义相似度等等.本文通过介绍DSSM.C ...
- 深入理解.NET Core的基元(三) - 深入理解runtimeconfig.json
原文:Deep-dive into .NET Core primitives, part 3: runtimeconfig.json in depth 作者:Nate McMaster 译文:深入理解 ...
- 最小路径算法(Dijkstra算法和Floyd算法)
1.单源点的最短路径问题:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径. 我们用一个例子来具体说明迪杰斯特拉算法的流程. 定义源点为 0,dist[i]为源点 0 到顶点 i 的最短路径 ...
- centos6安装pxc
Percona XtraDB Cluster是一种高可用性解决方案,可帮助企业避免停机和中断. Percona XtraDB Cluster具有以下MySQL群集优势: • 具有成本效益的HA和MyS ...
- jenkins 如何让job对应一个节点
1.配置job:如图,在label expression 里面填写[节点标签名]或者是[节点名称]. 2.配置节点: 3.构建:第一个红线,表明使用哪个节点进行构建. 第二个红线,表明工作目录.
- Windows下通过VMWare安装linux
VMWare虚拟机安装linux 虚拟机的概念 虚拟机,其本质其实也是一个程序. 但是这个程序,模仿了一台完整的主机常用的有 VMware,VirtualBox,Microsoft Virtual P ...
- wpa_supplicant的移植
解压,进入,使用默认配置文件 cd wpa_supplicant-2.6 cp defconfig .config 修改.config文件,修改部分,根据自己的需要进行这部分的配置 #指定libnl的 ...
- c获取shell中的参数
问题背景 在Linux中我们会使用到shell,来完成输入参数的获取,就如同下面的形式,这种形式在进行多语言编程和调用有着非常重要的作用 一.传递的过程 1.1 原理模型如下: 1.1.1 可执行sh ...
- iOS 日志获取和实时浏览器显示日志
https://juejin.im/entry/576252855bbb500063e51c7d iOS 日志获取和实时浏览器显示日志