python 多线程与线程池

简单的多线程—使用线程池
import time
import threading

def task_thread(counter):
    print(f'线程名称:{threading.current_thread().name} 参数:{counter} 开始时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
    num = counter
    while num:
        time.sleep(3)
        num -= 1
    print(f'线程名称:{threading.current_thread().name} 参数:{counter} 结束时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')


if __name__ == '__main__':
    print(f'主线程开始时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')

    #初始化3个线程,传递不同的参数
    t1 = threading.Thread(target=task_thread, args=(3,))
    t2 = threading.Thread(target=task_thread, args=(2,))
    t3 = threading.Thread(target=task_thread, args=(1,))
    #开启三个线程
    t1.start()
    t2.start()
    t3.start()
    #等待运行结束
    t1.join()
    t2.join()
    t3.join()

    print(f'主线程结束时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')

获取多线程返回值—使用线程池
from concurrent.futures import ThreadPoolExecutor
import time
request_param = ['lipei_00039.mp3', 'lipei_00044.mp3', 'lipei_00047.mp3', 'lipei_00049.mp3',
                  'lipei_00057.mp3', 'lipei_00058.mp3', 'lipei_00059.mp3', 'lipei_00061.mp3',
                  'lipei_00066.mp3', 'lipei_00068.mp3', 'lipei_00070.mp3', 'lipei_00081.mp3']
# 参数times用来模拟网络请求的时间
def action(max):
    print(max)
    time.sleep(0.2)
    return max+'_001'

if __name__ == '__main__':
    executor = ThreadPoolExecutor(max_workers=2)
    for data in executor.map(action, request_param):
        print("in main: get page {}s success".format(data))

使用 add_done_callback() 方法来获取线程任务的返回值

from concurrent.futures import ThreadPoolExecutor
import threading
import time

# 定义一个准备作为线程任务的函数
def action(max):
    my_sum = 0
    for i in range(max):
        print(threading.current_thread().name + '  ' + str(i))
        my_sum += i
    return my_sum
# 创建一个包含2条线程的线程池
with ThreadPoolExecutor(max_workers=2) as pool:
    future1 = pool.submit(action, 50)       # 向线程池提交一个task, 50会作为action()函数的参数
    future2 = pool.submit(action, 100)      # 向线程池再提交一个task, 100会作为action()函数的参数
    def get_result(future):
        print(future.result())
    future1.add_done_callback(get_result)      # 为future1添加线程完成的回调函数
    future2.add_done_callback(get_result)      # 为future2添加线程完成的回调函数
    print('--------------')

Exectuor 还提供了一个 map(func, *iterables, timeout=None, chunksize=1) 方法,该方法的功能类似于全局函数 map(),区别在于线程池的 map() 方法会为 iterables 的每个元素启动一个线程,以并发方式来执行 func 函数。这种方式相当于启动 len(iterables) 个线程,井收集每个线程的执行结果。

from concurrent.futures import ThreadPoolExecutor
import threading
import time


# 定义一个准备作为线程任务的函数
def action(max):
    my_sum = 0
    for i in range(max):
        print(threading.current_thread().name + '  ' + str(i))
        my_sum += i
    return my_sum
    
# 创建一个包含4条线程的线程池
with ThreadPoolExecutor(max_workers=4) as pool:
    # 使用线程执行map计算
    # 后面元组有3个元素,因此程序启动3条线程来执行action函数
    results = pool.map(action, (50, 100, 150))
    print('--------------')
    for r in results:
        print(r)
添加进度条(不是很准,但是能够起到参考作用)
from concurrent.futures import ThreadPoolExecutor
import time, sys, csv


def func(msg):
    print("raw:", msg)
    time.sleep(0.8)
    return msg + '_001'


request_params = ['lipei_00006.mp3', 'lipei_00007.mp3', 'lipei_00012.mp3',
                  'lipei_00021.mp3', 'lipei_00027.mp3', 'lipei_00028.mp3',
                  'lipei_00039.mp3', 'lipei_00044.mp3', 'lipei_00047.mp3',
                  'lipei_00057.mp3', 'lipei_00058.mp3', 'lipei_00059.mp3']

# 创建一个包含4条线程的线程池
with ThreadPoolExecutor(max_workers=4) as pool:
    scale = len(request_params)
    results = pool.map(func, request_params)  # 使用线程执行map计算
    Results = []
    for i, r in enumerate(results):
        a = '#' * int(i)
        b = '.' * (int(scale) - int(i))
        c = (i / scale) * 100
        Results.append(r)
        sys.stdout.write("{:^3.2f}%[{}->{}]".format(c, a, b))
        sys.stdout.flush()
    print('done!')
    # 保存返回值
    if len(Results) > 1:
        with open("./Results .csv", 'w', newline='') as csvfile:
            write = csv.writer(csvfile)
            write.writerow(Results)
    else:
        print('download ovor OK!')

参考:https://blog.csdn.net/somezz/article/details/80963760

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值