Python 多线程的实例详解
作者:攻城狮--晴明 发布时间:2023-09-24 23:15:04
Python 多线程的实例详解
一)线程基础
1、创建线程:
thread模块提供了start_new_thread函数,用以创建线程。start_new_thread函数成功创建后还可以对其进行操作。
其函数原型:
start_new_thread(function,atgs[,kwargs])
其参数含义如下:
function: 在线程中执行的函数名
args:元组形式的参数列表。
kwargs: 可选参数,以字典的形式指定参数
方法一:通过使用thread模块中的函数创建新线程。
>>> import thread
>>> def run(n):
for i in range(n):
print i
>>> thread.start_new_thread(run,(4,)) #注意第二个参数一定要是元组的形式
53840
1
>>>
2
3
KeyboardInterrupt
>>> thread.start_new_thread(run,(2,))
17840
1
>>>
thread.start_new_thread(run,(),{'n':4})
39720
1
>>>
2
3
thread.start_new_thread(run,(),{'n':3})
32480
1
>>>
2
方法二:通过继承threading.Thread创建线程
>>> import threading
>>> class mythread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num = num
def run(self): #重载run方法
print 'I am', self.num
>>> t1 = mythread(1)
>>> t2 = mythread(2)
>>> t3 = mythread(3)
>>> t1.start() #运行线程t1
I am
>>> 1
t2.start()
I am
>>> 2
t3.start()
I am
>>> 3
方法三:使用threading.Thread直接在线程中运行函数。
import threading
>>> def run(x,y):
for i in range(x,y):
print i
>>> t1 = threading.Thread(target=run,args=(15,20)) #直接使用Thread附加函数args为函数参数
>>> t1.start()
15
>>>
16
17
18
19
二)Thread对象中的常用方法:
1、isAlive方法:
>>> import threading
>>> import time
>>> class mythread(threading.Thread):
def __init__(self,id):
threading.Thread.__init__(self)
self.id = id
def run(self):
time.sleep(5) #休眠5秒
print self.id
>>> t = mythread(1)
>>> def func():
t.start()
print t.isAlive() #打印线程状态
>>> func()
True
>>> 1
2、join方法:
原型:join([timeout])
timeout: 可选参数,线程运行的最长时间
import threading
>>> import time #导入time模块
>>> class Mythread(threading.Thread):
def __init__(self,id):
threading.Thread.__init__(self)
self.id = id
def run(self):
x = 0
time.sleep(20)
print self.id
>>> def func():
t.start()
for i in range(5):
print i
>>> t = Mythread(2)
>>> func()
0
1
2
3
4
>>> 2
def func():
t.start()
t.join()
for i in range(5):
print i
>>> t = Mythread(3)
>>> func()
3
0
1
2
3
4
>>>
3、线程名:
>>> import threading
>>> class mythread(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name=threadname)
def run(self):
print self.getName()
>>>
>>> t1 = mythread('t1')
>>> t1.start()
t1
>>>
4、setDaemon方法
在脚本运行的过程中有一个主线程,如果主线程又创建了一个子线程,那么当主线程退出时,会检验子线程是否完成。如果子线程未完成,则主线程会在等待子线程完成后退出。
当需要主线程退出时,不管子线程是否完成都随主线程退出,则可以使用Thread对象的setDaemon方法来设置。
三)线程同步
1.简单的线程同步
使用Thread对象的Lock和RLock可以实现简单的线程同步。对于如果需要每次只有一个线程操作的数据,可以将操作过程放在acquire方法和release方法之间。如:
# -*- coding:utf-8 -*-
import threading
import time
class mythread(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name = threadname)
def run(self):
global x #设置全局变量
# lock.acquire() #调用lock的acquire方法
for i in range(3):
x = x + 1
time.sleep(2)
print x
# lock.release() #调用lock的release方法
#lock = threading.RLock() #生成Rlock对象
t1 = []
for i in range(10):
t = mythread(str(i))
t1.append(t)
x = 0 #将全局变量的值设为0
for i in t1:
i.start()
E:/study/<a href="http://lib.csdn.net/base/python" rel="external nofollow" class='replace_word' title="Python知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Python</a>/workspace>xianchengtongbu.py
3
6
9
12
15
18
21
24
27
30
如果将lock.acquire()和lock.release(),lock = threading.Lock()删除后保存运行脚本,结果将是输出10个30。30是x的最终值,由于x是全局变量,每个线程对其操作后进入休眠状态,在线程休眠的时候,Python解释器就执行了其他的线程而是x的值增加。当所有线程休眠结束后,x的值已被所有线修改为了30,因此输出全部为30。
2、使用条件变量保持线程同步。
python的Condition对象提供了对复制线程同步的支持。使用Condition对象可以在某些事件触发后才处理数据。Condition对象除了具有acquire方法和release的方法外,还有wait方法、notify方法、notifyAll方法等用于条件处理。
# -*- coding:utf-8 -*-
import threading
class Producer(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name = threadname)
def run(self):
global x
con.acquire()
if x == 1000000:
con.wait()
# pass
else:
for i in range(1000000):
x = x + 1
con.notify()
print x
con.release()
class Consumer(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name = threadname)
def run(self):
global x
con.acquire()
if x == 0:
con.wait()
#pass
else:
for i in range(1000000):
x = x - 1
con.notify()
print x
con.release()
con = threading.Condition()
x = 0
p = Producer('Producer')
c = Consumer('Consumer')
p.start()
c.start()
p.join()
c.join()
print x
E:/study/python/workspace>xianchengtongbu2.py
1000000
0
0
线程间通信:
Event对象用于线程间的相互通信。他提供了设置信号、清除信宏、等待等用于实现线程间的通信。
1、设置信号。Event对象使用了set()方法后,isSet()方法返回真。
2、清除信号。使用Event对象的clear()方法后,isSet()方法返回为假。
3、等待。当Event对象的内部信号标志为假时,则wait()方法一直等到其为真时才返回。还可以向wait传递参数,设定最长的等待时间。
# -*- coding:utf-8 -*-
import threading
class mythread(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name = threadname)
def run(self):
global event
if event.isSet():
event.clear()
event.wait() #当event被标记时才返回
print self.getName()
else:
print self.getName()
event.set()
event = threading.Event()
event.set()
t1 = []
for i in range(10):
t = mythread(str(i))
t1.append(t)
for i in t1:
i.start()
如有疑问请留言或者到本站社区交流讨论,感谢 阅读,希望能帮助到大家,谢谢大家对本站的支持!
来源:http://blog.csdn.net/qq_37267015/article/details/62923932
猜你喜欢
- 1、参数个数控制parser.add_argument('-i', '--integers', nargs=
- i前端:nput_test.html<!DOCTYPE html><html><head lang="
- PIL(Python Imaging Library)是Python中一个强大的图像处理库,但目前其只支持到Python2.7pillow是
- 前段时间,在pycharm里配置了远程的Python解释器,然后在使用过程中,发现pycharm原来是可以使用Jupyter的文件,而且还可
- 前言在pytorch中, 想删除tensor中的指定行列,原本以为有个函数或者直接把某一行赋值为[]就可以,结果发现没这么简单,因此用了一个
- 用yum更新PHP,只需用一条命令就可以搞定: #yum update php 但问题来了,使用此命令后,系统告诉我,没有发现可更新的包。而
- 前言提示:以下是本篇文章正文内容🍒PIL库概述PIL库支持图像存储、 显示和处理, 它能够处理几乎所有图片格式, 可以完成对图像的缩放、 剪
- 因为权限不够,导致Pycharm在运行脚本时报错:socket.error: [Errno 1] Operation not permitt
- 本文实例讲述了Python基于Matplotlib库简单绘制折线图的方法。分享给大家供大家参考,具体如下:Matplotlib画折线图,有一
- python3与python2的还是有诸多的不同,比如说在2中:print "Hello,World!" r
- Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义。一、函数式装饰器:装饰器本身是一个函数。1.装饰函数:被装饰对象
- 对会读书的人来说,读一本书要做的第一件事,就是仔细阅读这本书的目录。阅读目录可以对整体内容有所了解,并清楚地知道感兴趣的部分在哪里,提高阅读
- SVM支持向量机是建立于统计学习理论上的一种分类算法,适合与处理具备高维特征的数据集。SVM算法的数学原理相对比较复杂,好在由于SVM算法的
- chatGPT已经爆火一段时间了,我想大多数的开发者都在默默的在开发和测试当中,可能也是因为这个原因所以现在很难找到关于开发中遇到的一些坑或
- OK,今天我们来学习一下 python 中的日志模块,日志模块也是我们日后的开发工作中使用率很高的模块之一,接下来们就看一看今天具体要学习日
- 这篇文章主要介绍了Python FTP文件定时自动下载实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- 1. 介绍-- PHP5添加了一项新的功能:Reflection。这个功能使得phper可以reverse-engineer class,
- 使用del和drop方法删除DataFrame中的列,使用drop方法一次删除多列数据准备:import pandas as pd 
- 经常开发asp但对于细致的说法,真实不太清楚,这里简单的介绍下。一般情况下读取数据都是用rs.open sql,conn,1,1修改数据:r
- 发现问题比解决问题重要,使用php集成开发环境Appserv网页会提示各种语法错误,但自己配置开发环境无法提示错误,特别当不是语法错误,比如