鱼C论坛

 找回密码
 立即注册
查看: 3947|回复: 4

如何利用多进程来解决循环嵌套速度不行的问题?

[复制链接]
发表于 2017-6-8 08:56:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
有一个循环里面套循环的模式,在内循环的循环体内要同时用到大循环和小循环的变量。

我这里是简化成了一个简单的模型,
这种模式如果函数复杂的话速度超级慢,
想问一下如何使用多进程的办法来解决速度问题?

我的思路是,只对小循环采用多进程,
在大循环的循环体内写多进程的代码,
但是一直失败,
求大神给出正确的代码。

拜谢!

  1. import random as r
  2. list1=list(range(100))
  3. i=0
  4. reslist=[]
  5. while i<2000:#大循环
  6.     alist=[]#三个列表变量,每次循环开始时清空
  7.     blist=[]
  8.     clist=[]
  9.     for each in list1:#小循环
  10.         x=r.randint(i+30,i+60)+each#涉及到大、小循环变量的几个函数,这里用random示意
  11.         y=r.randint(i+60,i+120)+each
  12.         z=r.randint(i+60,i+180)+each
  13.         
  14.         res=2.5*x-y-z
  15.         reslist.append(res)#对函数结果进行操作
  16.         if res>=50:
  17.             alist.append(each)
  18.         if -50<res<50:
  19.             blist.append(each)
  20.         if res<=-50:
  21.             clist.append(each)
  22.             
  23.     for each in alist:#在大循环中对小循环中得出的结果进行进一步其他操作
  24.         print(each)
  25.     for each in blist:
  26.         print(each)
  27.     for each in clist:
  28.         print(each)
  29.    
  30.     i+=1
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-8 09:09:12 | 显示全部楼层
可以将循环的内容定义为一个函数,然后设置线程池,然后每次循环分配一个线程执行你的函数。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-8 12:22:33 | 显示全部楼层
本帖最后由 SixPy 于 2017-6-8 12:36 编辑

生产者、消费者 模式
  1. import threading
  2. import queue
  3. import random as r

  4. class 消费者(threading.Thread):
  5.     def __init__(self, queue, lock, name=''):
  6.         threading.Thread.__init__(self)
  7.         self._queue = queue
  8.         self.lock = lock
  9.         self.name = name

  10.     def run(self):
  11.         while 1:
  12.             msg = self._queue.get()
  13.             if isinstance(msg, str) and msg == 'quit':
  14.                 break
  15.             with self.lock:
  16.                  print("线程:%s,数据:%s" % (self.name, msg))
  17.                
  18.         with self.lock:
  19.             print("线程:%s 结束!" % self.name)

  20.         
  21. def 生产者():
  22.    
  23.     lck = threading.Lock() # 锁,用于同步 print()输出。
  24.     quels = [queue.Queue() for i in range(3)]# 数据队列
  25.     workers = [消费者(quels[n], lck, n) for n in range(3)]
  26.     for w in workers:
  27.         w.start()  # 开启消费者线程

  28.     for i in range(2000):#大循环
  29.         for q in quels:
  30.             q.queue.clear()#三个队列,每次循环开始时清空
  31.         for each in range(100):#小循环
  32.             x=r.randint(i+30,i+60)+each#涉及到大、小循环变量的几个函数,这里用random示意
  33.             y=r.randint(i+60,i+120)+each
  34.             z=r.randint(i+60,i+180)+each
  35.             
  36.             res=2.5*x-y-z
  37.             if res>=50:
  38.                 quels[0].put(each) # 数据压入队列,给消费线程使用
  39.             if -50<res<50:
  40.                 quels[1].put(each)
  41.             if res<=-50:
  42.                 quels[2].put(each)

  43.     for q in quels:
  44.         q.put('quit') # 线程退出消息
  45.    
  46.     for w in workers:
  47.         w.join()  # 等待消费者线程结束


  48. 生产者()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-8 13:01:05 | 显示全部楼层
SixPy 发表于 2017-6-8 12:22
生产者、消费者 模式

厉害厉害,因为是CPU密集型,我就直接去搜了多进程,多线程还没看,我先学习一下,先谢过大神。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-8 15:16:45 | 显示全部楼层
import random as r
import multiprocessing #进程模块
list1=list(range(100))
i=0
reslist=[]
count=[]
while i<2000:
    def test(): #打包
        alist=[]
        blist=[]
        clist=[]
        for each in list1:
            x=r.randint(i+30,i+60)+each
            y=r.randint(i+60,i+120)+each
            z=r.randint(i+60,i+180)+each
            
            res=2.5*x-y-z
            reslist.append(res)
            if res>=50:
                alist.append(each)
            if -50<res<50:
                blist.append(each)
            if res<=-50:
                clist.append(each)
               
        for each in alist: #多个进程同时输出到shell上,可能会出现很乱的情况,建议输出到其他地方
            print(each)
        for each in blist:
            print(each)
        for each in clist:
            print(each)
    go = multiprocessing.Process(target = test) #创建进程
    count.append(go)
    go.start()
    i+=1
    #子进程跟主进程并行,此时子进程继续工作的同时,大循环也在继续。
e = count.__len__() #计算含有进程元素的列表长度,长度为2000。
while True: #等待未完成的进程,当进程完成任务会消失,此时is.alive()返回false,减1长度,当长度为0,说明所有进程都完成任务。
    for each in count:
        if not each.is_alive():
            e -= 1
    if e <= 0:
        break
#帮你测试了下,还比线性慢了点
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-6 09:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表