Python回调函数中实现多线程调用的实战技巧

周末不加班
周末不加班
发布时间:2026-10-13 | 2人浏览过
原创

本文介绍如何在Python回调函数中安全使用多线程。通过示例演示如何处理不规则数据结构的回调逻辑,并重点讲解利用ThreadPool处理多参数函数的方法。对比多线程与多进程在CPU密集与IO密集型任务中的适用场景,提供从单参数到多参数映射的完整代码方案。

以下是一个基于实际需求编写的简易测试脚本。

#!/usr/bin/env python
# coding: utf-8
# 第一个列表为依赖组件和版本号,后面紧跟负责人名称
# 接着出现第二个以来组建列表,负责人为空了
# 所以根据需求需要对组件、版本号、负责人进行不同处理
# 这时在for循环中根据if判断,写回调函数处理
# 格式不一致数据的测试数据
a = [[u'tool-1', u'1.9.13'], u'xiaowang', u'xiaoqu', [u'tool-2', u'1.9.23'], [u'tool-3', u'1.9.33'], [u'tool-4', u'1.9.43'], u'pi',[u'tool-5', u'1.9.53']]
# a = [[u'tool-1', u'1.9.13'],u'xiaowang',[u'tool-2', u'1.9.23'],u'xiaowang', [u'tool-3', u'1.9.33'],u'xiaowang']
# a = [[u'tool-1', u'1.9.13']]
# [u'tool-1', u'1.9.13']
your_pro = a[0]
# print your_pro
# [u'xiaowang', u'xiaoqu', [u'tool-2', u'1.9.23']]
tmp = a[1:]
# print tmp
def git_callback(whole_v, proj_value, name_value):
  # 如果存在负责人存在
  try:
    if type(name_value[0]) is unicode:
      # 对除去列表0个索引的数据(依赖名和版本号)后面的数据进行遍历
      for i in name_value:
        # 碰到后面的数据是列表的进行回调
        if type(i) is list:
          tmp_index = whole_v.index(i)+1
          return git_callback(whole_v, whole_v[whole_v.index(i)], whole_v[tmp_index:])
        else:
          # 打印依赖、版本号 负责人 开始
          print proj_value+i.split()+['start']
    else:
      # 如果负责人后跟的组件这种格式的列表数据为空
      # 也就是只有依赖和版本号列表数据,负责人为空,就打印依赖版本号
      ver = proj_value
      owner = name_value
      if type(owner[0]) is unicode:
        return git_callback(whole_v, ver, owner)
      else:
        print ver
        # 这里是为了判断是不是到列表的最后一位
        # 如果是最后一个值,且不是字符串的Unicode,而是列表
        # 就直接打印出项目
        if whole_v.index(owner[0]) == len(whole_v)-1:
          # 打印最后一个值
          print whole_v[-1:]
        else:
          # 这里比较绕,打印调试吧...
          new_ver = whole_v[whole_v.index(ver)+1]
          owner = whole_v[whole_v.index(ver)+2:]
          return git_callback(whole_v, new_ver, owner)
  except IndexError as e:
    print proj_value
    print e
git_callback(a, your_pro, tmp)

该测试脚本的运行输出结果如下所示。

Boom:git_response pirogue$ python test.py
[u'tool-1', u'1.9.13', u'xiaowang', 'start']
[u'tool-1', u'1.9.13', u'xiaoqu', 'start']
[u'tool-2', u'1.9.23']
[u'tool-3', u'1.9.33']
[u'tool-4', u'1.9.43', u'pi', 'start']
[u'tool-5', u'1.9.53']
list index out of range

关于Python多线程的基础应用。

以下代码片段是从主程序中剥离出来的核心部分。

from multiprocessing.dummy import Pool as ThreadPool
# 判断git查询返回的依赖数据格式不唯一的回调
def git_callback(whole_v, proj_value, name_value, git_cookie):
  # 
  whole_v = whole_v
  list_git = []
  if name_value:
    # print name_value
    for i in name_value:
      # print i
      if i:
        if type(i) is list:
          tmp_index = whole_v.index(i)+1
          return git_callback(whole_v, whole_v[whole_v.index(i)], whole_v[tmp_index:], git_cookie)
        else:
          git_cookie = str(git_cookie.split()[0])+' '+str(git_cookie.split()[1])
          list_git.append(tuple(git_cookie.split("?")+i.split()))
          print list_git
          pool = ThreadPool(100)
          result = pool.map(pool_git, list_git)
          print result
          pool.close()
          pool.join()          
  else:
    print proj_value

上述多线程代码片段封装在一个回调函数中,并未完全按照初始demo进行重构。实际上,基于该demo根据具体需求进行调整并不困难,关键在于多次调试优化。

探讨Python多线程如何接收多个参数。

from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(100)
result = pool.map(pool_git, list_git)
print result
pool.close()
pool.join()

其中,是你希望通过多线程调用的目标功能函数,而则是传递给的参数列表。在默认情况下,通常设计为仅接收单个参数。

然而,实际业务逻辑往往较为复杂,需要在中传入多个参数。此时,应当被构造为一个包含多个元组的列表,以适配多参数传递的需求。

以下是Stack Overflow上提供的代码示例,展示了多参数传递的处理方式。

def multi_run_wrapper(args):
  return add(*args)
def add(x,y):
  return x+y
if __name__ == "__main__":
  from multiprocessing import Pool
  pool = Pool(4)
  results = pool.map(multi_run_wrapper,[(1,2),(2,3),(3,4)])
  print results
output
[3, 5, 7]

此外,Stack Overflow上还有更多相关的答疑内容,有助于你更深入地理解这一机制。

参考链接:https://stackoverflow.com/questions/5442910/python-multiprocessing-pool-map-for-multiple-arguments

相信具备一定基础的开发者能够轻松理解上述示例。

多线程与多进程的对比分析。

from multiprocessing.dummy import Pool as ThreadPool

多线程线程池通常绑定到一个CPU核心运行。

from multiprocessing import Pool

多进程则可以利用多个CPU核心并行运行。

如果你难以判断任务是CPU密集型还是IO密集型,可以采用一种折中方案:同时导入两个库,分别实例化并测试耗时。在用法上,只需将创建对象时的类名从改为即可互换使用。

总结。

以上内容介绍了在Python回调函数中使用多线程的方法,希望能对大家有所帮助。如有任何疑问,欢迎留言,小编会及时回复。感谢大家对本站的支持!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表