簡體   English   中英

在python中並行執行任務

[英]Executing tasks in parallel in python

我使用的是python 2.7,我有一些看起來像這樣的代碼:

task1()
task2()
task3()
dependent1()

task4()
task5()
task6()
dependent2()

dependent3()

這里唯一的依賴關系如下:dependent1需要等待tasks1-3,dependent2需要等待任務4-6,dependent3需要等待dependents1-2 ......以下就可以了:先運行整個6個任務並行,然后前兩個家屬並行..然后最終依賴

我喜歡盡可能多地並行運行任務,我已經搜索了一些模塊,但我希望避免使用外部庫,並且不確定Queue-Thread技術如何解決我的問題(也許有人可以推薦一個好資源) ?)

內置的threading.Thread類提供了你所需要的一切: 開始一個新的線程並加入以等待一個線程的結束。

import threading

def task1():
    pass
def task2():
    pass
def task3():
    pass
def task4():
    pass
def task5():
    pass
def task6():
    pass

def dep1():
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task2)
    t3 = threading.Thread(target=task3)

    t1.start()
    t2.start()
    t3.start()

    t1.join()
    t2.join()
    t3.join()

def  dep2():
    t4 = threading.Thread(target=task4)
    t5 = threading.Thread(target=task5)

    t4.start()
    t5.start()

    t4.join()
    t5.join()

def dep3():
    d1 = threading.Thread(target=dep1)
    d2 = threading.Thread(target=dep2)

    d1.start()
    d2.start()

    d1.join()
    d2.join()

d3 = threading.Thread(target=dep3)
d3.start()
d3.join()

或者,您可以使用Queue.join等待線程結束。

如果您願意為外部庫提供一個鏡頭,您可以使用Ray優雅地表達任務及其依賴關系。 這在單個機器上運行良好,這里的優點是使用Ray比使用python多處理更容易表達並行性和依賴性,並且它沒有經常阻止多線程高效工作的GIL(全局解釋器鎖定)問題。 此外,如果將來需要,可以非常輕松地在群集上擴展工作負載。

解決方案如下所示:

import ray

ray.init()

@ray.remote
def task1():
    pass

@ray.remote
def task2():
    pass

@ray.remote
def task3():
    pass

@ray.remote
def dependent1(x1, x2, x3):
    pass

@ray.remote
def task4():
    pass

@ray.remote
def task5():
    pass

@ray.remote
def task6():
    pass

@ray.remote
def dependent2(x1, x2, x3):
    pass

@ray.remote
def dependent3(x, y):
    pass

id1 = task1.remote()
id2 = task2.remote()
id3 = task3.remote()

dependent_id1 = dependent1.remote(id1, id2, id3)

id4 = task4.remote()
id5 = task5.remote()
id6 = task6.remote()

dependent_id2 = dependent2.remote(id4, id5, id6)

dependent_id3 = dependent3.remote(dependent_id1, dependent_id2)

ray.get(dependent_id3) # This is optional, you can get the results if the tasks return an object

您還可以通過使用任務內部的參數並返回結果來傳遞任務之間的實際python對象(例如,說“返回值”而不是上面的“傳遞”)。

使用“pip install ray”,上面的代碼在一台機器上開箱即用,並且很容易並行化群集上的應用程序,無論是在雲端還是您自己的自定義群集中,請參閱https://ray.readthedocs。 io / en / latest / autoscaling.htmlhttps://ray.readthedocs.io/en/latest/using-ray-on-a-cluster.html )。 如果您的工作量在以后增長,那么這可能會派上用場。

免責聲明:我是Ray的開發人員之一。

看看Gevent

用法示例:

import gevent
from gevent import socket

def destination(jobs):
    gevent.joinall(jobs, timeout=2)
    print [job.value for job in jobs]

def task1():
    return gevent.spawn(socket.gethostbyname, 'www.google.com')

def task2():
    return gevent.spawn(socket.gethostbyname, 'www.example.com')

def task3():
    return gevent.spawn(socket.gethostbyname, 'www.python.org')

jobs = []
jobs.append(task1())
jobs.append(task2())
jobs.append(task3())
destination(jobs)

希望,這是你一直在尋找的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM