Python 多线程

本文介绍了使用多线程解决Django项目中MySQL数据库查询效率低下的方法,通过实例展示了如何优化多任务处理及数据聚合过程,提供了在Python环境下进行高效并行处理的实践指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

第一种解决方案:

import multiprocessing
def 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把所有到当作对象来处理,传的参数可以叫做对象对象引用。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值