Memproses DAG dengan async Python dan graphlib

王林
Lepaskan: 2024-08-27 06:37:09
asal
443 orang telah melayarinya

Processing DAGs with async Python and graphlib

Saya baru-baru ini menjumpai modul yang menarik dalam perpustakaan standard Python yang tidak berdasar: graphlib. Jika anda tidak pernah menggunakannya sebelum ini, ia adalah utiliti kecil yang telah ditambahkan dalam Python 3.9 dan hanya melaksanakan satu kelas: TopologicalSorter.

Namanya jelas -- ini ialah kelas untuk pengisihan topologi graf. Tetapi saya tidak fikir ia pada asalnya ditulis dengan hanya menyusun dalam fikiran, kerana ia mempunyai API yang agak samar, tetapi sangat berguna, seperti kaedah prepare() atau is_active(). Contoh dalam dokumentasi ini membayangkan motivasi di sebaliknya:

topological_sorter = TopologicalSorter() # Add nodes to 'topological_sorter'... topological_sorter.prepare() while topological_sorter.is_active(): for node in topological_sorter.get_ready(): # Worker threads or processes take nodes to work on off the # 'task_queue' queue. task_queue.put(node) # When the work for a node is done, workers put the node in # 'finalized_tasks_queue' so we can get more nodes to work on. # The definition of 'is_active()' guarantees that, at this point, at # least one node has been placed on 'task_queue' that hasn't yet # been passed to 'done()', so this blocking 'get()' must (eventually) # succeed. After calling 'done()', we loop back to call 'get_ready()' # again, so put newly freed nodes on 'task_queue' as soon as # logically possible. node = finalized_tasks_queue.get() topological_sorter.done(node)
Salin selepas log masuk

Jadi graphlib bukan modul hanya untuk mengisih graf, ia juga merupakan utiliti untuk menjalankan graf tugas dalam susunan topologi, yang berguna jika beban kerja anda mempunyai tugas bergantung pada hasil tugasan lain. Graf ialah cara terbaik untuk memodelkan masalah ini dan susunan topologi ialah cara anda memastikan tugasan diproses dalam susunan yang betul.

Satu perkara yang hilang daripada dokumen ialah contoh asyncio, yang ternyata agak mudah untuk ditulis. Memandangkan dengan asyncio anda tidak perlu berurusan dengan keselamatan benang, anda boleh bertahan tanpa menggunakan baris gilir untuk menyegerakkan utas atau sebarang kerumitan tambahan lain seperti itu.

Kami akan mentakrifkan fungsi pelawat nod async ringkas:

async def visit(node: str, sorter: TopologicalSorter): print(f"processing node {node}") sorter.done(node)
Salin selepas log masuk

Dalam dunia nyata ini boleh menjadi sekompleks yang anda mahukan, selagi anda melakukan kerja terikat I/O jadi nikmatilah faedah asyncio. Perkara yang penting ialah memanggil sorter.done(nod) di penghujung fungsi untuk memberitahu contoh TopologicalSorter bahawa kita telah selesai dengan nod ini dan kita boleh maju ke seterusnya.

Kemudian kami palamkan fungsi lawatan ke dalam larian tersusun topologi kami:

sorter = TopologicalSorter(graph) sorter.prepare() while sorter.is_active(): node_group = sorter.get_ready() if not node_group: # no nodes are ready yet, so we sleep for a bit await asyncio.sleep(0.25) else: tasks = set() for node in node_group: task = asyncio.create_task(visit(node, sorter)) tasks.add(task) task.add_done_callback(tasks.discard)
Salin selepas log masuk

Kod sumber penuh skrip yang berfungsi boleh didapati dalam intipati ini.

Satu aspek pelik graphlib ialah format graf yang diterima oleh TopologicalSorter sebagai hujah -- ia adalah dalam susunan terbalik daripada perwakilan graf biasa anda. Cth. jika anda mempunyai graf seperti ini A -> B -> C, biasanya anda akan mewakilinya seperti ini:

graph = { "A": ["B"], "B": ["C"], "C": [], }
Salin selepas log masuk

tetapi TopologicalSorter mahu graf ini dalam arah tepi diterbalikkan:

Jika hujah graf pilihan disediakan, ia mestilah kamus yang mewakili graf akiklik terarah dengan kekuncinya ialah nod dan nilainya boleh diulang daripada semua pendahulu nod tersebut dalam graf

Jadi cara yang betul untuk mewakili A -> B -> C untuk TopologicalSorter ialah ini:

graph = { "C": ["B"], "B": ["A"], "A": [], }
Salin selepas log masuk

Maklumat lanjut dan perdebatan yang agak hangat tentang perkara ini boleh didapati di sini: https://bugs.python.org/issue46071.

Selamat mengekod!

Atas ialah kandungan terperinci Memproses DAG dengan async Python dan graphlib. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!