Python 3 -多线程编程

Python 3 -多线程编程

随着互联网的普及和计算机技术的不断发展,现在我们的电脑可以一边看视频,一边打游戏,同时还可以开着浏览器、文本编辑器等等。这就要归功于多线程技术。多线程是一种让计算机同时处理多个任务的技术,可以提高程序运行的效率,尤其是对于网络编程,因为可以同时处理多个网络请求,从而提高服务器的处理能力,降低用户等待的时长。Python 3提供了丰富的多线程编程方法,本文将介绍Python 3中的多线程编程,供读者学习和参考。

Python中的多线程模块

Python 3中提供了两种多线程模块:thread和threading,其中,thread模块已经被废弃,使用threading模块可以更好的进行多线程编程。

使用threading模块需要导入该模块,代码如下:

import threading

通过创建线程对象并启动线程,来运行多线程程序。创建线程对象的方法有两种:

  1. 通过继承Thread类创建线程
import threading

class MyThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:" + self.name)
        # 线程执行的代码
        print ("退出线程:" + self.name)

# 创建新线程
thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

print ("退出主线程")
  1. 通过直接调用Thread类的构造函数创建线程
import threading

def print_time(threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % (threadName, time.ctime(time.time())))

# 创建新线程
thread1 = threading.Thread(target=print_time, args=("Thread-1", 1))
thread2 = threading.Thread(target=print_time, args=("Thread-2", 2))

# 开启新线程
thread1.start()
thread2.start()

print ("退出主线程")

多线程的基本操作

启动线程

在Python 3中,启动线程有两种方法:继承Thread类和直接创建Thread对象。使用Thread类方法时,只需要在创建线程对象时设定要执行的函数;而使用直接创建Thread对象的方法时,需要将要执行的函数作为target参数来传递。

import threading

# 定义执行的函数
def print_time(threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % (threadName, time.ctime(time.time())))

# 使用继承Thread类方法创建线程
class MyThread (threading.Thread):
    def __init__(self, threadID, name, counter, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.delay = delay
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.delay)
        print ("退出线程:" + self.name)

# 创建新线程
thread1 = MyThread(1, "Thread-1", 1, 1)
thread2 = MyThread(2, "Thread-2", 2, 2)

# 开启新线程
thread1.start()
thread2.start()

print ("退出主线程")

线程同步

多线程编程中,线程之间会相互干扰,甚至导致数据错误,因此需要进行线程同步。Python 3中提供了Lock、RLock、Semaphore、Event等同步机制。

Lock

Lock类是最基本的同步原语,提供了多线程操作时的排他性。在需要使用共享资源的代码块中,程序可以调用acquire()方法获得锁,当程序执行完毕后,使用release()方法释放锁。

import threading

lock = threading.Lock()

class MyThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:" + self.name)
        # 获取锁
        lock.acquire()
        print_time(self.name, self.counter)
        # 释放锁
        lock.release()
        print ("退出线程:" + self.name)

# 创建新线程
thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

print ("退出主线程")

RLock

RLock类是可重入锁,即允许一个线程多次获取同一个锁,其方式与Lock类相同。

import threading

lock = threading.RLock()

class MyThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:"+ self.name)
        lock.acquire()
        print_time(self.name, self.counter)
        lock.release()
        print ("退出线程:"+self.name)

thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)

thread1.start()
thread2.start()

print ("退出主线程")

Semaphore

Semaphore类是允许多个线程同时访问一定数量资源的同步机制,通常用于限制同时访问一个资源的线程数量。

import threading

semaphore = threading.Semaphore(2)

class MyThread (threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
    def run(self):
        print ("开始线程:"+ self.name)
        semaphore.acquire()
        print_time(self.name, self.delay)
        semaphore.release()
        print ("退出线程:"+self.name)

thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)
thread3 = MyThread(3, "Thread-3", 3)

thread1.start()
thread2.start()
thread3.start()

print ("退出主线程")

Event

Event类用于线程之间的通信,一个线程通知另一个线程某个事件发生。一个线程可以等待事件,也可以重置事件。

import threading

event = threading.Event()

class MyThread (threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
    def run(self):
        print ("开始线程:" + self.name)
        # 等待事件
        event.wait()
        print_time(self.name, self.delay)
        print ("退出线程:" + self.name)

thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)

thread1.start()
thread2.start()

time.sleep(2)
# 事件触发
event.set()

print ("退出主线程")

线程优先级

线程在执行时,可能会强制停止,转而执行其他线程的操作,这就是线程优先级。线程优先级在Python 3中可以设置,但是既使设置了优先级,也不能完全按照优先级执行,因为Python 3没有提供严格的优先级保证。

在Python 3中,线程的优先级有三个等级:LOWEST、LOW、NORMAL、HIGH、HIGHEST,使用threading模块中Thread类的set_priority()函数可以进行设置。默认情况下,所有线程都是NORMAL级别的。

import threading

class MyThread (threading.Thread):
   def __init__(self, threadID, name, priority):
      threading.Thread.__init__(self)
      self.threadID = threadID
      self.name = name
      self.priority = priority
   def run(self):
      print ("开始线程:" + self.name)
      print_time(self.name, self.priority)
      print ("退出线程:" + self.name)

thread1 = MyThread(1, "Thread-1", threading.ThreadPriority.HIGHEST)
thread2 = MyThread(2, "Thread-2", threading.ThreadPriority.LOW)

thread1.start()
thread2.start()

print ("退出主线程")

多线程的应用和注意事项

线程池

线程池是一种常见的线程管理方式,它可以控制线程数量的上限,并且重复利用已经创建的线程。线程池的优点在于减少线程的创建和销毁开销,同时提高程序的可伸缩性,降低程序的资源占用等。

在Python 3中,可以使用ThreadPoolExecutor 类来实现线程池,代码如下:

from concurrent.futures import ThreadPoolExecutor
import threading

def print_time(threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % (threadName, time.ctime(time.time())))

# 创建线程池
threadPool = ThreadPoolExecutor(max_workers=2)

# 提交任务
future1 = threadPool.submit(print_time, "Thread-1", 1)
future2 = threadPool.submit(print_time, "Thread-2", 2)

# 等待任务完成
future1.result()
future2.result()

print ("退出主线程")

注意事项

  • 多线程编程需要考虑线程的安全性和同步性,对临界资源进行保护,避免竞争条件的出现。
  • 多线程编程需要考虑资源的分配,合理的分配线程,避免创建过多的线程导致资源的浪费。
  • 多线程编程在处理I/O密集型任务中会遇到一些问题,如果线程的数量多了,很有可能会降低性能,使用协程的方式来解决这个问题。

结论

Python 3提供了多种多样的多线程编程方法,可以方便地实现多线程编程,提高程序的效率。本文介绍了Python 3中的多线程模块,以及多线程的基本操作、同步、优先级设置、线程池和注意事项。希望本文可以对Python 3多线程编程感兴趣的读者提供一些参考和帮助。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程