Python同时运行两个循环,其中一个是速率限制的,依赖于oth的数据

2024-04-28 13:14:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python中遇到了一个问题,我想同时运行两个循环。我觉得我需要这样做,因为第二个循环需要速率限制,但是第一个循环实际上不应该是速率限制的。另外,第二个循环接受第一个循环的输入。在

我要找的是这样的东西:

for line in file:
do some stuff
list = []
list.append("an_item")

Rate limited:
for x in list:
do some stuff simultaneously

Tags: inanforrate速率linesomeitem
2条回答

有两种基本方法具有不同的折衷:在任务之间同步切换,在线程或子进程中运行。首先,一些常见的设置:

from queue import Queue # or Queue, if python 2
work = Queue()

def fast_task():
    """ Do the fast thing """
    if done:
        return None
    else:
        return result

def slow_task(arg):
    """ Do the slow thing """

RATE_LIMIT = 30 # seconds

现在,同步方法。它的优点是简单得多,调试更容易,但代价是速度慢一点。慢多少取决于你的任务细节。它的工作原理是,我们运行一个紧密的循环,每次调用快速作业,只有经过足够的时间后,才调用慢速作业。如果快速作业不再产生工作,并且队列是空的,那么我们退出。在

^{pr2}$

如果您觉得这样做不够快,可以尝试^{}方法。您可以使用相同的结构来处理线程或进程,具体取决于您是从multiprocessing.dummy还是从multiprocessing本身导入。我们使用multiprocessing.Queue代替queue.Queue进行通信。在

def do_the_fast_loop(work_queue):
    while True:
        next_job = fast_task()
        if next_job:
            work_queue.put(next_job)
        else:
            work_queue.put(None) # sentinel - tells slow process to quit
            break

def do_the_slow_loop(work_queue):
    next_call = time.time()
    while True:
        job = work_queue.get()
        if job is None: # sentinel seen - no more work to do
            break
        time.sleep(max(0, next_call - time.time()))
        next_call = time.time() + RATE_LIMIT
        slow_task(job)

if __name__ == '__main__':
    # from multiprocessing.dummy import Queue, Process # for threads
    from multiprocessing import Queue, Process # for processes
    work = Queue()
    fast = Process(target=fast_task, args=(work,))
    slow = Process(target=slow_task, args=(work,))
    fast.start()
    slow.start()
    fast.join()
    slow.join()

正如您所看到的,有相当多的机器需要您实现,但是它会更快一些。同样,速度有多快在很大程度上取决于你的任务。我会尝试这三种方法——同步、线程和多进程——看看你最喜欢哪种。在

你需要做两件事:

  1. 将函数require另一个函数的数据放在自己的进程中
  2. 实现两个进程之间的通信方式(例如Queue

所有这些都必须归功于GIL。在

相关问题 更多 >