在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 就可以自动完成所有的线程管理。
