Mai mult
Cum să utilizați filetare în Python?
Am încercat să înțeleg de filetare în Python. Am'am uitat la documentare și exemple, dar destul de sincer, de multe exemple sunt prea sofisticate și am'm având probleme în a le înțelege.
Cum vă arată în mod clar sarcinile fiind împărțite pentru multi-threading?
1204
19
Când această întrebare a fost întrebat în 2010, a existat o simplificare reală în modul de a face simplu multithreading cu python cu harta și biliard.
Codul de mai jos vine de la un articol/post pe blog că ar trebui să verificați cu siguranta (nici o afiliere) - Paralelism într-o singură linie: Un Model Mai bun pentru o zi la Zi de Filetat Sarcini. Am'll rezuma mai jos - se termină prin a fi doar câteva linii de cod:
Care este multithreaded versiune de:
Descriere
Implementarea
multiprocesare.dummy
este exact la fel ca multiprocesare modulului, dar foloseste fire în loc (o distincție importantă - utilizați mai multe procese pentru CPU-intensive sarcini; fire (și în timpul) IO):Și calendarul rezultate:
Trecerea de mai multe argumente (funcționează ca aceasta numai în Python 3.3 și mai târziu):
Pentru a trece mai multe tablouri:
sau să treacă o constantă și o matrice:
Dacă utilizați o versiune anterioară de Python, puteți trece mai multe argumente prin această soluție.
(Vă mulțumim pentru user136036 pentru comentariu util)
Aici's un exemplu simplu: ai nevoie pentru a încerca o alternativă câteva Url-uri și de a reveni la conținutul de primul pentru a răspunde.
Acesta este un caz în filetat este utilizat ca un simplu optimizare: fiecare subthread este în așteptare pentru un URL pentru a rezolva și de a răspunde, în scopul de a pune conținutul său pe coada; fiecare subiect este un daemon (a castigat't menține procesul dacă firul principal se termină ... asta's mult mai frecvente decât nu); firul principal începe subthreads, nu o "a lua" la coadă să aștepte până când unul dintre ei a făcut-o "pune", apoi emite rezultatele și se termină (care ia în jos orice subthreads care ar mai putea fi difuzate, deoarece acestea're fire daemon).
Utilizarea corectă a firelor în Python este invariabil legat de operațiunile de I/O (din CPython nu't de a folosi mai multe nuclee pentru a rula CPU-bound sarcini oricum, singurul motiv pentru filetare nu este blocarea procesului în timp ce nu's-o așteptați de ceva I/O). Cozile sunt aproape invariabil, cel mai bun mod pentru ferma de muncă la fire și/sau să colecteze munca's rezultatele, de altfel, și-au're intrinsec sigură pentru fire deci se salva de la griji despre încuietori, condiții, evenimente, semafoare și alte inter-thread coordonare/comunicare concepte.
NOTĂ: efectiv Pentru paralelizare în Python, ar trebui să utilizați multiprocesare module pentru a plăti mai multe procese care se execută în paralel (ca urmare a interpret global de blocare, Python fire oferi intercalarea dar sunt, de fapt, executate în serie, nu in paralel, si sunt utile numai atunci când intercalarea operațiuni I/O).
Cu toate acestea, dacă sunteți doar în căutarea pentru intercalarea (sau se fac operațiuni de I/O care pot fi paralelizate în ciuda globale interpret de blocare), apoi filetare modulul este locul pentru a începe. Ca un exemplu simplu, să's ia în considerare problema de însumând o gamă largă prin însumarea subranges în paralel:
Rețineți că cele de mai sus este un foarte prost exemplu, ca nu-i absolut nici I/O și vor fi executate în serie, deși intercalat (cu a adăugat aeriene din context switching) în CPython din cauza globale interpret de blocare.
Ca și alții menționat, CPython pot folosi fire doar pentru am\O așteaptă din cauza GIL. Dacă doriți să beneficiați de mai multe nuclee de CPU-bound sarcinile, utilizați multiprocesare:
Doar o notă, Coada nu este necesară pentru filetare.
Acesta este cel mai simplu exemplu am putea imagina că arată 10 procese care rulează în același timp.
Răspunsul la Alex Martelli m-a ajutat, cu toate acestea, aici este o versiune modificată care am crezut eu că e mai util (cel putin pentru mine).
Actualizat: funcționează în ambele python2 și python3
Am găsit acest lucru foarte util: a crea cât mai multe fire ca nuclee și lăsați-le să execute o (mare) numărul de sarcini (în acest caz, de asteptare un program shell):
Având o funcție "f", fir astfel:
Pentru a trece de argumente pentru a "f"
Python 3-a facilitatea de Lansarea paralel sarcini. Acest lucru face munca mai ușoară.
A pentru fir comun și Proces comun.
Următoarele vă oferă o imagine de ansamblu:
ThreadPoolExecutor Exemplu
ProcessPoolExecutor
Pentru mine, exemplul perfect pentru Filetare este monitorizarea evenimente Asincrone. Uita-te la acest cod.
Te poti juca cu acest cod prin deschiderea unui IPython sesiune și de a face ceva de genul:
Așteptați câteva minute
Folosind aprins nou concurente.futures modulul
Executorul abordare ar putea părea familiar pentru toți cei care au ajuns pe mâinile lor murdare cu Java înainte.
De asemenea, pe o parte notă: Pentru a menține universul sănătos, don't uitați să închideți piscine/executorii, dacă nu't folosi " cu " context (care este atât de minunat că o face pentru tine)
Cele mai multe documentații și tutoriale folosi Python's
Filetat
și "Coadă", modulul ar putea părea copleșitoare pentru incepatori.Poate lua în considerare simultane.contracte futures.ThreadPoolExecutor` modulul de python 3. Combinat cu " cu " clauză și lista de înțelegere ar putea fi un real farmec.
Am văzut o mulțime de exemple aici, unde nu au fost efectuate + au cea mai mare unitate PROCESOR legat. Aici este un exemplu de un PROCESOR legat de sarcina care calculează toate numerele prime între 10 milioane și 10.05 milioane de euro. Eu am folosit toate cele 4 metode aici
Aici sunt rezultatele pe Mac OSX 4 core mașină
Aici este foarte simplu exemplu de import CSV folosind filetare. [Biblioteca de incluziune pot să difere pentru diferite scop ]
Funcțiile Helper:
Funcții De Conducere:
Multi threading cu simplu exemplu care va fi de ajutor. Puteți rula și de a înțelege cu ușurință cum este multi firul de lucru în python. Am folosit de blocare pentru a preveni accesul altor fire până anterioare fire terminat munca lor. Prin utilizarea de
această linie de cod puteți permite numere de proces la un moment dat și țineți apăsat pentru restul de fir care se va desfășura mai târziu sau după ce a terminat anterior procese.
Niciuna dintre soluțiile de mai sus, de fapt, folosit de mai multe nuclee pe GNU/Linux server (în cazul în care nu't ai drepturi de admin). Au fugit pe un singur nucleu. Am folosit mai mic nivel de `os.furculiță pentru interfata să ruleze mai multe procese. Acesta este codul care a lucrat pentru mine:
Aș dori să contribuie cu un exemplu simplu și explicații am'am găsit util atunci când am avut de a aborda aceasta problema.
În acest răspuns, veți găsi unele informații despre Python's GIL (Global Interpret de Blocare) și o simplă zi cu zi de exemplu scris folosind multiprocesare.dummy plus unele repere simple.
Global Interpret de Blocare (GIL)
Python nu't permite multi-threading în adevăratul sens al cuvântului. Ea are un multi-threading pachet dar dacă vrei să-multi-thread pentru a accelera codul, apoi se's, de obicei, nu este o idee bună să-l folosească. Python are un construct numit Global Interpret de Blocare (GIL). GIL face sigur că doar unul din 'fire' poate executa la un moment dat. Un fir dobândește GIL, face un pic de lucru, apoi trece la GIL pe lângă fir. Acest lucru se întâmplă foarte repede, astfel încât ochiul uman nu poate părea ca subiectele sunt de executare în paralel, dar ei sunt doar ținând transformă folosind același CPU core. Toate acestea GIL trecerea adaugă aeriană de la executie. Acest lucru înseamnă că, dacă doriți pentru a face codul alerga mai repede apoi, folosind filetare pachet de multe ori e't o idee bună.
Există motive pentru a folosi Python's filetare pachet. Dacă doriți să rulați unele lucruri simultan, iar eficiența nu este un motiv de îngrijorare, apoi se's în regulă și convenabil. Sau dacă executați codul care trebuie să așteptați pentru ceva (cum ar fi unele IO), atunci s-ar putea face o mulțime de sens. Dar filetare biblioteca a câștigat't să utilizați suplimentar de nuclee CPU.
Multi-threading pot fi externalizate către sistemul de operare (de a face multi-processing), unele aplicații externe care solicită codul Python (de exemplu, Scânteie sau Hadoop), sau un cod care Python codul de apeluri (de exemplu: ai putea să-ți cod Python sun o C funcția care face scumpe multi-threaded chestii).
De Ce Acest Lucru Contează
Pentru că o mulțime de oameni petrec o mulțime de timp încercând să găsească blocaje în lor de lux Python multi-threaded de cod înainte de a învăța ce-i GIL.
Odată ce această informație este clar aici's codul meu:
Cu împrumut de la acest mesaj știm despre alegerea între multithreading, multiprocesare, și asincron și utilizarea lor.
Python3 are o nouă bibliotecă built-in pentru concurență și paralelism: concurente.futures
Așa că am demonstra printr-un experiment la care rulează patru sarcini (de exemplu
.sleep ()
) metoda de Filetare-Pool` mod:Out:
[NOTĂ]:
3
muncitori pentru cei patru sarcini.ThreadPoolExecutor " cu " ProcessPoolExecutor