Python多线程方法详解
什么是多线程
多线程是一种利用CPU多核的并发编程方式,它利用CPU在一段时间内分配给不同线程的时间片,来让不同线程交替执行,从而达到并发执行的效果。
Python多线程模块
Python标准库提供了两种主要的多线程模块:_thread
和threading
。其中,_thread
是低级别的模块,主要提供了一些底层的线程操作函数,比如start_new_thread()
来创建一个新线程。而threading
则是高级别的模块,因此更易用,提供了更多的功能,比如线程锁、事件、信号等等。
使用threading模块创建多线程
假设我们需要在程序中执行两个任务:打印1-5的数字和打印a-e的字母。我们可以使用threading
模块来实现多线程。
import threading
def print_numbers():
for i in range(1, 6):
print(i)
def print_letters():
for letter in ['a', 'b', 'c', 'd', 'e']:
print(letter)
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
t1.start()
t2.start()
t1.join()
t2.join()
print('Done.')
上述代码中,我们创建了两个线程t1
和t2
,分别去执行print_numbers()
和print_letters()
函数,然后启动两个线程,等待两个线程执行完后再打印Done.
。
线程同步
多线程协作的时候,由于线程交替执行,可能会导致一些问题,比如线程之间的数据通信、变量共享可能会存在竞争风险。为了避免这种情况,我们需要使用线程同步的机制,比如锁。
import threading
def increment():
global counter
for i in range(1000000):
lock.acquire()
counter += 1
lock.release()
def decrement():
global counter
for i in range(1000000):
lock.acquire()
counter -= 1
lock.release()
counter = 0
lock = threading.Lock()
t1 = threading.Thread(target=increment)
t2 = threading.Thread(target=decrement)
t1.start()
t2.start()
t1.join()
t2.join()
print('Counter:', counter)
上述代码中,我们创建了一个计数器counter
,然后分别开启了两个线程t1
和t2
,分别去调用increment()
和decrement()
函数,它们都会对计数器进行加一和减一的操作,预期的结果应该是counter
的值还是0。
要做到这一点,我们需要使用Lock
对象来对计数器进行同步,确保同一时刻只有一个线程会对计数器进行修改。
示例1:多线程抓取网页内容
import requests
import threading
def fetch_url(url):
response = requests.get(url)
print('Fetched %s with %d bytes.' % (url, len(response.content)))
urls = [
'http://www.baidu.com',
'http://www.sina.com',
'http://www.163.com',
]
threads = []
for url in urls:
t = threading.Thread(target=fetch_url, args=(url,))
threads.append(t)
t.start()
for t in threads:
t.join()
print('Done.')
上述代码中,我们定义了一个fetch_url()
函数,用来读取指定URL的内容。然后创建了三个URL,使用三个线程并发执行,最后等待所有线程都结束后再打印Done.
。
示例2:多线程下载图片
import requests
import threading
def download(url, filename):
response = requests.get(url)
with open(filename, 'wb') as f:
f.write(response.content)
urls = [
'http://img1.mm131.me/pic/1738/1.jpg',
'http://img1.mm131.me/pic/1738/2.jpg',
'http://img1.mm131.me/pic/1738/3.jpg',
]
threads = []
for idx, url in enumerate(urls):
t = threading.Thread(target=download, args=(url, f'{idx}.jpg'))
threads.append(t)
t.start()
for t in threads:
t.join()
print('Done.')
上述代码中,我们定义了一个download()
函数,用来下载指定URL的图片,并保存到本地。然后创建了三个URL,使用三个线程并发下载,最后等待所有线程都结束后再打印Done.
。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python多线程方法详解 - Python技术站