Python 自学:使用线程模块同时运行代码 Threading

1. 以下代码中,程序会等一个函数执行完毕才执行下一个函数。

import time

start = time.perf_counter()

def do_something():
    print('Sleeping 1 second...')
    time.sleep(1)
    print('Done Sleeping...')

do_something()
do_something()

finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')


输出为:
Sleeping 1 second…
Done Sleeping…
Sleeping 1 second…
Done Sleeping…
Finished in 2.02 second(s)

Python 自学:使用线程模块同时运行代码 Threading_第1张图片

2. 以下代码中,一个函数开始执行后,另一个函数也会立刻开始执行。

import time
import threading

start = time.perf_counter()

def do_something():
    print('Sleeping 1 second...')
    time.sleep(1)
    print('Done Sleeping...')

t1 = threading.Thread(target=do_something)
t2 = threading.Thread(target=do_something)

t1.start()
t2.start()

t1.join()
t2.join()

finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')


Python 自学:使用线程模块同时运行代码 Threading_第2张图片

3. 执行一个队列的线程

import time
import threading

start = time.perf_counter()

def do_something(seconds):
    print(f'Sleeping {seconds} second(s)...')
    time.sleep(seconds)
    print('Done Sleeping...')

threads = []
for _ in range(10):
    t = threading.Thread(target = do_something, args=[1.5])
    t.start()
    threads.append(t)

for thread in threads:
    thread.join()

finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')


输出为:
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Sleeping 1.5 second(s)…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Done Sleeping…
Finished in 1.52 second(s)

4. 使用concurrent.futures库中的线程池

import time
import concurrent.futures

start = time.perf_counter()

def do_something(seconds):
    print(f'Sleeping {seconds} second(s)...')
    time.sleep(seconds)
    return 'Done Sleeping...'

with concurrent.futures.ThreadPoolExecutor() as executor:
    f1 = executor.submit(do_something, 1)
    f2 = executor.submit(do_something, 1)

    print(f1.result())
    print(f2.result())

finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')


输出为:
Sleeping 1 second(s)…
Sleeping 1 second(s)…
Done Sleeping…
Done Sleeping…
Finished in 1.02 second(s)

5. 使用map()函数执行一个数组的输入

import time
import concurrent.futures

start = time.perf_counter()

def do_something(seconds):
    print(f'Sleeping {seconds} second(s)...')
    time.sleep(seconds)
    return f'Done Sleeping...{seconds}'

with concurrent.futures.ThreadPoolExecutor() as executor:
    secs = [5, 4, 3, 2, 1]
    results = executor.map(do_something, secs)

    for result in results:
        print(result)

finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')


输出为:
Sleeping 5 second(s)…
Sleeping 4 second(s)…
Sleeping 3 second(s)…
Sleeping 2 second(s)…
Sleeping 1 second(s)…
Done Sleeping…5
Done Sleeping…4
Done Sleeping…3
Done Sleeping…2
Done Sleeping…1
Finished in 5.01 second(s)

6. 使用线程同时下载图片

先看一下不使用线程的版本:

import requests
import time

img_urls = [
    'https://images.unsplash.com/photo-1516117172878-fd2c41f4a759',
    'https://images.unsplash.com/photo-1532009324734-20a7a5813719',
    'https://images.unsplash.com/photo-1524429656589-6633a470097c',
    'https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
    'https://images.unsplash.com/photo-1564135624576-c5c88640f235',
    'https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
    'https://images.unsplash.com/photo-1522364723953-452d3431c267',
    'https://images.unsplash.com/photo-1513938709626-033611b8cc03',
    'https://images.unsplash.com/photo-1507143550189-fed454f93097',
    'https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
    'https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
    'https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
    'https://images.unsplash.com/photo-1516972810927-80185027ca84',
    'https://images.unsplash.com/photo-1550439062-609e1531270e',
    'https://images.unsplash.com/photo-1549692520-acc6669e2f0c'
]

time1 = time.perf_counter()

for img_url in img_urls:
    img_bytes = requests.get(img_url).content
    img_name = img_url.split('/')[3]
    img_name = f'{img_name}.jpg'

    with open(img_name, 'wb') as img_file:
        img_file.write(img_bytes)
        print(f'{img_name} was downloaded.')


time2 = time.perf_counter()

print(f'finish in {time2-time1} seconds')

输出为:
photo-1516117172878-fd2c41f4a759.jpg was downloaded.
photo-1532009324734-20a7a5813719.jpg was downloaded.
photo-1524429656589-6633a470097c.jpg was downloaded.
photo-1530224264768-7ff8c1789d79.jpg was downloaded.
photo-1564135624576-c5c88640f235.jpg was downloaded.
photo-1541698444083-023c97d3f4b6.jpg was downloaded.
photo-1522364723953-452d3431c267.jpg was downloaded.
photo-1513938709626-033611b8cc03.jpg was downloaded.
photo-1507143550189-fed454f93097.jpg was downloaded.
photo-1493976040374-85c8e12f0c0e.jpg was downloaded.
photo-1504198453319-5ce911bafcde.jpg was downloaded.
photo-1530122037265-a5f1f91d3b99.jpg was downloaded.
photo-1516972810927-80185027ca84.jpg was downloaded.
photo-1550439062-609e1531270e.jpg was downloaded.
photo-1549692520-acc6669e2f0c.jpg was downloaded.
finish in 3.0728321000933647 seconds

以下是使用线程的版本,时间缩短了1秒

import requests
import time
import concurrent.futures

img_urls = [
    'https://images.unsplash.com/photo-1516117172878-fd2c41f4a759',
    'https://images.unsplash.com/photo-1532009324734-20a7a5813719',
    'https://images.unsplash.com/photo-1524429656589-6633a470097c',
    'https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
    'https://images.unsplash.com/photo-1564135624576-c5c88640f235',
    'https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
    'https://images.unsplash.com/photo-1522364723953-452d3431c267',
    'https://images.unsplash.com/photo-1513938709626-033611b8cc03',
    'https://images.unsplash.com/photo-1507143550189-fed454f93097',
    'https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
    'https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
    'https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
    'https://images.unsplash.com/photo-1516972810927-80185027ca84',
    'https://images.unsplash.com/photo-1550439062-609e1531270e',
    'https://images.unsplash.com/photo-1549692520-acc6669e2f0c'
]

time1 = time.perf_counter()

def download_image(img_url):
    img_bytes = requests.get(img_url).content
    img_name = img_url.split('/')[3]
    img_name = f'{img_name}.jpg'

    with open(img_name, 'wb') as img_file:
        img_file.write(img_bytes)
        print(f'{img_name} was downloaded.')

with concurrent.futures.ThreadPoolExecutor() as executor:
    executor.map(download_image, img_urls)

time2 = time.perf_counter()

print(f'finish in {time2-time1} seconds')

输出为:
photo-1516117172878-fd2c41f4a759.jpg was downloaded.
photo-1507143550189-fed454f93097.jpg was downloaded.
photo-1513938709626-033611b8cc03.jpg was downloaded.
photo-1516972810927-80185027ca84.jpg was downloaded.
photo-1550439062-609e1531270e.jpg was downloaded.
photo-1564135624576-c5c88640f235.jpg was downloaded.
photo-1532009324734-20a7a5813719.jpg was downloaded.
photo-1524429656589-6633a470097c.jpg was downloaded.
photo-1541698444083-023c97d3f4b6.jpg was downloaded.
photo-1530122037265-a5f1f91d3b99.jpg was downloaded.
photo-1549692520-acc6669e2f0c.jpg was downloaded.
photo-1522364723953-452d3431c267.jpg was downloaded.
photo-1493976040374-85c8e12f0c0e.jpg was downloaded.
photo-1530224264768-7ff8c1789d79.jpg was downloaded.
photo-1504198453319-5ce911bafcde.jpg was downloaded.
finish in 2.0237455000169575 seconds

线程适用于涉及IO的操作,例如上面演示的下载图片。但是,如果是涉及CPU的操作,例如处理图片,使用线程反而可能令程序执行速度下降。

你可能感兴趣的:(Python,python)