欢迎访问宙启技术站
智能推送

在Python中实现多线程函数并发编程

发布时间:2023-06-22 11:50:32

Python是一个支持多线程编程的语言,其标准库中提供了多个模块和函数,方便用户实现多线程编程。多线程编程可以提高程序的并行处理能力,充分利用多核CPU的优势,提升程序的性能。

一、多线程模块

Python中的多线程模块包括threading、_thread、Queue、Semaphore等。

1.threading模块

threading是Python中的一个高级多线程模块,提供了Thread类,可用于创建和管理线程。通过继承Thread类,用户可以自定义线程类,并重写run()方法实现线程的逻辑。

以下是一个简单的例子:

import threading

class MyThread(threading.Thread):
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):
        print("Thread", self.num, "is running...")

if __name__ == "__main__":
    thread1 = MyThread(1)
    thread2 = MyThread(2)
    thread1.start()
    thread2.start()

2._thread模块

_thread是Python的低级线程模块,提供了一些基本的线程函数和操作。虽然_thread与threading有些相似,但_thread更为底层,使用时需要注意线程同步和线程安全问题。

以下是一个例子:

import _thread

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

try:
    _thread.start_new_thread(print_time, ("Thread-1", 1))
    _thread.start_new_thread(print_time, ("Thread-2", 2))
except:
    print("Error: unable to start thread")

3.Queue模块

Queue模块是Python提供的线程安全的队列类,可用于在多线程间传递数据。

以下是一个简单的例子:

import threading
import queue

q = queue.Queue()
q.put("Hello")
q.put("World")
print(q.get())
print(q.get())

4.Semaphore模块

Semaphore是Python提供的同步原语,用于控制和限制多个线程对共享资源的访问数量。

以下是一个例子:

import threading

semaphore = threading.Semaphore(2)

def task(name):
    semaphore.acquire()
    print("Task", name, "started")
    time.sleep(2)
    print("Task", name, "ended")
    semaphore.release()

if __name__ == "__main__":
    for i in range(5):
        t = threading.Thread(target=task, args=(i,))
        t.start()

二、多线程编程实践

1.下载多个URL

以下是一个例子,通过多线程下载多个URL:

import threading
import requests
import time

# URL列表
url_list = [
    "http://www.example.com/",
    "http://www.example.org/",
    "http://www.example.net/",
    "http://www.example.edu/",
    "http://www.example.co.uk/"
]

class DownloadThread(threading.Thread):
    def __init__(self, url):
        threading.Thread.__init__(self)
        self.url = url

    def run(self):
        print("Start downloading", self.url)
        start_time = time.time()
        response = requests.get(self.url)
        end_time = time.time()
        print("Downloaded", len(response.content), "bytes from", self.url, "in", end_time - start_time, "seconds")

if __name__ == "__main__":
    threads = []
    for url in url_list:
        thread = DownloadThread(url)
        threads.append(thread)

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

2.计算素数

以下是使用多线程计算素数的例子:

import threading

# 计算素数
def is_prime(num):
    if num < 2:
        return False
    for i in range(2, int(num ** 0.5) + 1):
        if num % i == 0:
            return False
    return True

# 计算区间内的素数数量
def count_primes(start, end):
    count = 0
    for i in range(start, end):
        if is_prime(i):
            count += 1
    return count

# 多线程计算素数
class PrimeThread(threading.Thread):
    def __init__(self, start, end):
        threading.Thread.__init__(self)
        self.start = start
        self.end = end
        self.result = None

    def run(self):
        self.result = count_primes(self.start, self.end)

if __name__ == "__main__":
    threads = []
    n = 100000
    chunk_size = n // 4
    for i in range(4):
        start = i * chunk_size + 1
        end = (i + 1) * chunk_size
        thread = PrimeThread(start, end)
        threads.append(thread)

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

    count = sum(thread.result for thread in threads)
    print("There are", count, "primes between 1 and", n)

以上两个例子都是用线程池技术,可以参考 concurrent.futures.Pool() 函数,通过提供 CPU 核心数,快速的创建即可。这样 Python 就可以自动完成所有的线程管理。