Python 多线程

来源:互联网 发布:放到网络上的英文 编辑:程序博客网 时间:2024/05/22 17:08

        最近在用django进行开发,后台用到MySQL数据库,由于查询语句的嵌套,实现起来是在太慢,之前师兄跟我提过用多线程进行操作,我也没怎么接触过,于是就搁置一旁了,当时的主要目的是为了赶出几个小东西,就没有太在意速度这个问题,其实当时也在思考过这个可能是“最关键”的问题。

       终于项目赶出来了一点小的成果,就遇到速度的问题,就开始多线程之旅,下面是我总结的一些小小的代码经验,仅供大家参考。  

第一种解决方案:

import multiprocessingdef multiTask(tasklist,host,port,user,password,database,item_tbname,keyword,search_rule):for i in range(0,len(tasklist),20):   # 每次取20个任务        tasktemp = tasklist[i:i+20]        job=[]    # 初始化每次执行的线程        if i <20:            print(getDate()+":"+"Begin_Project:"+str(len(tasklist)))        print(getDate()+":"+"Process:"+str(round((i+10)*100/len(tasklist),0))+"%")        for j in range(0,len(tasktemp)):     # 此处创建20个线程            ptask = (host,port,user,password,database,item_tbname,keyword,search_rule,tasktemp[j][0])            # info            p = multiprocessing.Process(target = func,args=(ptask,))    # func是运行的函数名称,args是传入的参数            p.start()            job.append(p)        for p in job:            p.join()</span>

       此处注意的是有两个函数值得注意,一个就是start(),另一个就是join(),在这里我就不详细展开说了,相信大家都可以百度谷歌到,我想提醒大家一个的就是对于下面这条语句

p = multiprocessing.Process(target = func,args=(ptask,))

       这个函数的func后面不用加括号(),还有如果只有一个蚕食一定记得后面的args中的逗号‘,’不要遗漏,这是为了标注args是一个list。


第二种解决方案:

         第一种解决方案基本上可以解决一些基本的多线程问题,后来我想加入list参数,让每个线程执行的结果作为一个dict拼接到一起,可是怎么弄都没有很好的解决这个问题,也是捣鼓半天,后来就想换种解决方案。主要参考网上一位仁兄的代码:Python多线程异步获得多函数调用的返回值 ,稍加修改就行了,下面贴出我修改的代码:

class MyThread(object):    def __init__(self, func_list=None):        self.func_list = func_list        self.threads = []    def set_thread_func_list(self, func_list):        """        @note: func_list是一个list,每个元素是一个dict,有func和args两个参数        """        self.func_list = func_list    @staticmethod    def trace_func(func, *args, **kwargs):        """        @note:替代profile_func,新的跟踪线程返回值的函数,对真正执行的线程函数包一次函数,以获取返回值        """        func(*args, **kwargs)    def start(self):        """        @note: 启动多线程执行,并阻塞到结束        """        self.threads = []        for func_dict in self.func_list:            if func_dict["args"]:                new_arg_list = [func_dict["func"]]                for arg in func_dict["args"]:                    new_arg_list.append(arg)                new_arg_tuple = tuple(new_arg_list)                task = threading.Thread(target=self.trace_func, args=new_arg_tuple)            else:                task = threading.Thread(target=self.trace_func, args=(func_dict["func"],))            self.threads.append(task)        for thread_obj in self.threads:            thread_obj.start()        for thread_obj in self.threads:            thread_obj.join()</span>

for i in range(0, len(Result_itemnum), 5):       tasktemp_itemnum = Result_itemnum[i:i + 5]       mt = MyThread()       g_func_list = []       for j in range(0, len(tasktemp_itemnum)):       g_func_list.append(             {"func": self.run_itemnum,             "args": (selectdb, ordertable, itemtable, category, day, sellernick, tasktemp_itemnum[j][0], List_te)})       mt.set_thread_func_list(g_func_list)       mt.start()

       其中下面一部分是我自己实现的一些代码,其中参数部分的List_te是我传进去的参数。基本上能实现一些参数的修改,Python中没有C语言中所谓的传值与传引用的差别,Python把所有到当作对象来处理,传的参数可以叫做对象对象引用。






0 0