python 多线程二

  之前写过一个简单的python多线程,算是简单入门了。不过随着涉及的工作内容越来越深,简单的多线程可能已经无法满足我的需求。比如:

给你一批手机号,然后通过一个登录接口获取每个手机的token,或者uid,如果用单线程的话,可能会需要很长一段时间,因为涉及到网络原因+网络传输,无论如何你都要等下去。但是如果你用多线程的话,尽管python多线程存在着GIL的问题,但是对于涉及到I/O的需求,多线程还是可以满足的。这个可以把网络的时间给省下来。说到这里,回头可以考虑用多进程试试。下面是我贴的一个源码,我用了list来替代手机号。大致原理一样,可以参考一下。

#!/usr/bin/env python
# encoding: utf-8
'''
@author: shd
@time: 2020/1/1 19:10
@desc:
'''

from mutiDeom.mutiThread import calculate_time
from threading import Thread
from queue import Queue
from time import sleep


# 创建一个list, 用来操作
def create_list():
    return [i for i in range(1,110)]

@calculate_time
def normal_cal(): # 普通的单线程方法
    # s=list(map(lambda x:x**2+x**3,create_list()))
    result_list = []
    for item in create_list():
        sleep(0.1) # 使用sleep 来模拟网络时间
        result_list.append(item**2 +item **3)
    print(result_list)


#自定义多线程
class Mythread(Thread):
    def __init__(self,thread_id,q,s,e):
        '''

        :param thread_id:  线程id 此次不需要
        :param q:      队列,把每个线程返回的值通过q.put()放入其中
        :param s:    列表开始的值
        :param e:   列表结束的值
        '''
        Thread.__init__(self)
        self.thread_id = thread_id
        self.s  =s
        self.e = e
        self.q = q
        #重写run方法
    def run(self):
        jisuanList(self.q,self.s,self.e)


#多线程的job
def jisuanList(q,s,e):
    global pre_list
    # pre_list = create_list()
    for i in range(s,e):
        sleep(0.1) # 使用sleep 来模拟网络时间
        q.put(pre_list[i]**2 +pre_list[i]**3)


# 开启多线程
@calculate_time
def open_thread():
    global  pre_list    # 定义全局的列表
    pre_list = create_list()
    total_num = 5     # 线程总数
    step = int(len(pre_list)/total_num)  #计算每个线程的步数

    threads = [] #存放所有的线程
    q = Queue()  #定义队列
    for i in range(5):
        if i == 0:
            t = Mythread("thread_id is{}".format(i),q,0,step)
            t.start()
        elif 5 == i+1 :
            t = Mythread("thread_id is{}".format(i), q, i*step, len(pre_list))
            t.start()
        else:
            t = Mythread("thread_id is{}".format(i), q, i * step,(i+1)*step )
            t.start()
        threads.append(t)

    for t in threads:
        t.join()
    result_list = []
    for _ in range(len(pre_list)):
        result_list.append(q.get()) # 通过队列获取每个线程的值
    print(result_list)


if __name__ == '__main__':
    normal_cal()
    open_thread()



#output
open_thread函数耗费的时间是2.5612778663635254
normal_cal函数耗费的时间是11.166929006576538

你可能感兴趣的:(python 多线程二)