鱼C论坛

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

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

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

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

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

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

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

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

拜谢!
import random as r
list1=list(range(100))
i=0
reslist=[]
while i<2000:#大循环
    alist=[]#三个列表变量,每次循环开始时清空
    blist=[]
    clist=[]
    for each in list1:#小循环
        x=r.randint(i+30,i+60)+each#涉及到大、小循环变量的几个函数,这里用random示意
        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:#在大循环中对小循环中得出的结果进行进一步其他操作
        print(each)
    for each in blist:
        print(each)
    for each in clist:
        print(each)
    
    i+=1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

生产者、消费者 模式
import threading
import queue
import random as r

class 消费者(threading.Thread):
    def __init__(self, queue, lock, name=''):
        threading.Thread.__init__(self)
        self._queue = queue
        self.lock = lock
        self.name = name

    def run(self):
        while 1:
            msg = self._queue.get()
            if isinstance(msg, str) and msg == 'quit':
                break
            with self.lock:
                 print("线程:%s,数据:%s" % (self.name, msg))
                
        with self.lock:
            print("线程:%s 结束!" % self.name)

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

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

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


生产者()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

厉害厉害,因为是CPU密集型,我就直接去搜了多进程,多线程还没看,我先学习一下,先谢过大神。
想知道小甲鱼最近在做啥?请访问 -> 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
#帮你测试了下,还比线性慢了点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-8 13:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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