Python 多线程编程实战:从创建到同步详解

一颗松果
一颗松果
发布时间:2026-10-13| 5人浏览过
原创

本文详细解析 Python 多线程编程的核心概念与实现方法。内容涵盖使用 thread 模块、继承 Thread 类及直接指定 target 三种线程创建方式,深入讲解 Thread 对象的常用方法如 join、setDaemon 等。重点阐述利用 Lock、Condition 和 Event 对象实现线程同步与通信,通过代码示例演示如何处理竞态条件及线程间信号交互,帮助开发者掌握并发编程的关键技术。

Python 多线程编程实战详解

一、线程基础概念

1. 创建线程的三种主要方式

Python 中的 thread 模块提供了 start_new_thread 函数,用于创建新的线程。该函数在成功创建线程后,允许对线程进行进一步的操作。其函数原型如下:

  start_new_thread(function,atgs[,kwargs])

该函数的参数含义如下:

function:指定在线程中执行的函数名称。 args:以元组形式传递的参数列表。 kwargs:可选参数,以字典形式指定参数。

方法一:利用 thread 模块中的 start_new_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 类,并通过 target 参数指定在线程中运行的函数。

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() 方法返回 True。 2. 清除信号:使用 Event 对象的 clear() 方法后,isSet() 方法返回 False。 3. 等待:当 Event 对象的内部信号标志为 False 时,wait() 方法会一直等待,直到信号变为 True 时才返回。还可以向 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() 

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。