京公网安备 11010802034615号
经营许可证编号:京B2-20210330
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创建线程

方法三:使用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()
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在构建前向神经网络(Feedforward Neural Network,简称 FNN)时,“隐藏层数目设多少?每个隐藏层该放多少个神经元?” 是每个 ...
2025-10-29这个问题切中了 Excel 用户的常见困惑 —— 将 “数据可视化工具” 与 “数据挖掘算法” 的功能边界混淆。核心结论是:Excel 透 ...
2025-10-29在 CDA(Certified Data Analyst)数据分析师的工作中,“多组数据差异验证” 是高频需求 —— 例如 “3 家门店的销售额是否有显 ...
2025-10-29在数据分析中,“正态分布” 是许多统计方法(如 t 检验、方差分析、线性回归)的核心假设 —— 数据符合正态分布时,统计检验的 ...
2025-10-28箱线图(Box Plot)作为展示数据分布的核心统计图表,能直观呈现数据的中位数、四分位数、离散程度与异常值,是质量控制、实验分 ...
2025-10-28在 CDA(Certified Data Analyst)数据分析师的工作中,“分类变量关联分析” 是高频需求 —— 例如 “用户性别是否影响支付方式 ...
2025-10-28在数据可视化领域,单一图表往往难以承载多维度信息 —— 力导向图擅长展现节点间的关联结构与空间分布,却无法直观呈现 “流量 ...
2025-10-27这个问题问到了 Tableau 中两个核心行级函数的经典组合,理解它能帮你快速实现 “相对位置占比” 的分析需求。“index ()/size ( ...
2025-10-27对 CDA(Certified Data Analyst)数据分析师而言,“假设检验” 绝非 “套用统计公式的机械操作”,而是 “将模糊的业务猜想转 ...
2025-10-27在数字化运营中,“凭感觉做决策” 早已成为过去式 —— 运营指标作为业务增长的 “晴雨表” 与 “导航仪”,直接决定了运营动作 ...
2025-10-24在卷积神经网络(CNN)的训练中,“卷积层(Conv)后是否添加归一化(如 BN、LN)和激活函数(如 ReLU、GELU)” 是每个开发者都 ...
2025-10-24在数据决策链条中,“统计分析” 是挖掘数据规律的核心,“可视化” 是呈现规律的桥梁 ——CDA(Certified Data Analyst)数据分 ...
2025-10-24在 “神经网络与卡尔曼滤波融合” 的理论基础上,Python 凭借其丰富的科学计算库(NumPy、FilterPy)、深度学习框架(PyTorch、T ...
2025-10-23在工业控制、自动驾驶、机器人导航、气象预测等领域,“状态估计” 是核心任务 —— 即从含噪声的观测数据中,精准推断系统的真 ...
2025-10-23在数据分析全流程中,“数据清洗” 恰似烹饪前的食材处理:若食材(数据)腐烂变质、混杂异物(脏数据),即便拥有精湛的烹饪技 ...
2025-10-23在人工智能领域,“大模型” 已成为近年来的热点标签:从参数超 1750 亿的 GPT-3,到万亿级参数的 PaLM,再到多模态大模型 GPT-4 ...
2025-10-22在 MySQL 数据库的日常运维与开发中,“更新数据是否会影响读数据” 是一个高频疑问。这个问题的答案并非简单的 “是” 或 “否 ...
2025-10-22在企业数据分析中,“数据孤岛” 是制约分析深度的核心瓶颈 —— 用户数据散落在注册系统、APP 日志、客服记录中,订单数据分散 ...
2025-10-22在神经网络设计中,“隐藏层个数” 是决定模型能力的关键参数 —— 太少会导致 “欠拟合”(模型无法捕捉复杂数据规律,如用单隐 ...
2025-10-21在特征工程流程中,“单变量筛选” 是承上启下的关键步骤 —— 它通过分析单个特征与目标变量的关联强度,剔除无意义、冗余的特 ...
2025-10-21