Python vairāku pavedienu un daudzprocesu apmācība

Izmēģiniet Mūsu Instrumentu Problēmu Novēršanai

Diskusijās, kurās tiek kritizēts Python, bieži tiek runāts par to, cik grūti ir izmantot Python daudzšķiedru darbam, norādot ar pirkstiem uz tā saukto globālo tulku ...



Piezīme: Pēc tautas pieprasījuma, lai es demonstrētu dažas alternatīvas metodes, tostarp asinhronizāciju/gaidīšanu, kas ir pieejamas tikai kopš Python 3.5 parādīšanās, esmu pievienojis daži atjauninājumi raksta beigās . Izbaudi!






Diskusijās, kurās tiek kritizēts Python, bieži tiek runāts par to, kā ir grūti izmantot Python daudzšķiedru darbam, norādot ar pirkstiem uz tā saukto globālo tulku bloķēšanu (sirsnīgi saukta par GIL ), kas neļauj vienlaikus darboties vairākiem Python koda pavedieniem. Šī iemesla dēļ daudzpavedienu modulis Python nedarbojas tā, kā jūs to gaidītu, ja neesat Python izstrādātājs un jūs nākat no citām valodām, piemēram, C ++ vai Java. Jāpaskaidro, ka Python joprojām var rakstīt kodu, kas darbojas vienlaikus vai paralēli, un būtiski mainīt iegūto veiktspēju, ja vien tiek ņemtas vērā dažas lietas. Ja vēl neesat to lasījis, iesaku apskatīt Eqbal Korānu raksts par vienlaicīgumu un paralēlismu rubīnā šeit Toptal Engineering Blog.



Šajā Python vienlaicīguma apmācībā mēs uzrakstīsim nelielu Python skriptu, lai lejupielādētu populārākos Imgur attēlus. Mēs sāksim ar versiju, kas attēlus lejupielādē secīgi vai pa vienam. Kā priekšnoteikums jums būs jāreģistrējas lietojumprogramma vietnē Imgur . Ja jums vēl nav Imgur konta, vispirms izveidojiet to.



Šo pavedienu piemēru skripti ir pārbaudīti ar Python 3.6.4. Ar dažām izmaiņām tiem vajadzētu darboties arī ar Python 2 - urllib ir tas, kas visvairāk mainījies starp šīm divām Python versijām.






mainīt pasīvo balsi uz aktīvo balss pārveidotāju

Darba sākšana ar Python multithreading

Sāksim, izveidojot Python moduli ar nosaukumu | _+_ |. Šajā failā būs visas funkcijas, kas vajadzīgas, lai ielādētu attēlu sarakstu un tos lejupielādētu. Mēs sadalīsim šīs funkcijas trīs atsevišķās funkcijās:

  • download.py
  • get_links
  • download_link

Trešā funkcija | _+_ | tiks izmantota, lai izveidotu lejupielādes galamērķa direktoriju, ja tā vēl nav.

Imgur API prasa, lai HTTP pieprasījumos būtu | _+_ | galvene ar klienta ID. Šo klienta ID varat atrast tās lietojumprogrammas informācijas panelī, kuru esat reģistrējis vietnē Imgur, un atbilde būs JSON kodēta. Mēs varam izmantot Python standarta JSON bibliotēku, lai to atšifrētu. Attēla lejupielāde ir vēl vienkāršāks uzdevums, jo viss, kas jums jādara, ir iegūt attēlu pēc tā URL un ierakstīt failā.

Skripts izskatās šādi:

setup_download_dir

Palaižot šo Python pavedienu parauga skriptu tajā pašā datorā, kas tika izmantots iepriekš, lejupielādes laiks ir 4,1 sekunde! Tas ir 4,7 reizes ātrāk nekā iepriekšējā piemērā. Lai gan tas ir daudz ātrāk, ir vērts pieminēt, ka GIL dēļ šajā procesā vienlaikus tika izpildīts tikai viens pavediens. Tāpēc šis kods ir vienlaicīgs, bet nav paralēls. Iemesls, kāpēc tas joprojām ir ātrāks, ir tas, ka tas ir saistīts ar IO. Procesors gandrīz nesalauž sviedrus, lejupielādējot šos attēlus, un lielākā daļa laika tiek pavadīts, gaidot tīklu. Tāpēc Python daudzpavedieni var ievērojami palielināt ātrumu. Procesors var pārslēgties starp pavedieniem, kad viens no tiem ir gatavs veikt kādu darbu. Izmantojot pavedienu moduli Python vai jebkurā citā interpretētā valodā ar GIL, faktiski var samazināties veiktspēja. Ja jūsu kods veic ar CPU saistītu uzdevumu, piemēram, gzip failu atspiešanu, izmantojot | _+_ | moduļa izpildes laiks būs lēnāks. CPU saistītiem uzdevumiem un patiesi paralēlai izpildei mēs varam izmantot daudzapstrādes moduli.

Kamēr de facto atsauce Python ieviešanai - CPython - ir GIL, tas neattiecas uz visām Python ieviešanām. Piemēram, IronPython, Python ieviešanai, kurā tiek izmantota .NET sistēma, nav GIL, kā arī nav Java ieviešanai Jython. Jūs varat atrast strādājošo Python ieviešanu sarakstu šeit .

Saistīts: Toptal izstrādātāju Python paraugprakse un padomi ] ( https://www.toptal.com/python/tips-and-practices ) https://www.toptal.com/python/tips-and-practices ))

Vienlaicīgums un paralēlisms Python 2. piemērs: vairāku procesu nārstošana

Daudzapstrādes moduli ir vieglāk ievietot nekā pavedienu moduli, jo mums nav jāpievieno klase, piemēram, Python pavedienu piemērs. Vienīgās izmaiņas, kas mums jāveic, ir pamatfunkcijā.

Lai izmantotu vairākus procesus, mēs izveidojam daudzprocesu | _+_ |. Izmantojot tajā paredzēto kartes metodi, mēs nodosim URL sarakstu kopumam, kas savukārt radīs astoņus jaunus procesus un izmantos katru no tiem, lai paralēli lejupielādētu attēlus. Tas ir īsts paralēlisms, taču tam ir izmaksas. Visa skripta atmiņa tiek kopēta katrā apakšprocesā, kas tiek radīts. Šajā vienkāršajā piemērā tas nav liels darījums, bet tas var viegli kļūt par nopietnām izmaksām, kas nav svarīgas programmas.

setup_download_dir

Vienlaicīgums un paralēlisms Python 3. piemērs: izplatīšana vairākiem darbiniekiem

Lai gan pavedienu vākšanas un daudzapstrādes moduļi ir lieliski piemēroti skriptiem, kas darbojas jūsu personālajā datorā, kas jums jādara, ja vēlaties, lai darbs tiktu veikts ar citu mašīnu, vai arī jums ir jāpalielina līdz vairāk nekā CPU vienā mašīnā rokturis? Lielisks piemērs tam ir ilgstoši back-end uzdevumi tīmekļa lietojumprogrammām. Ja jums ir daži ilgstoši uzdevumi, jūs nevēlaties vienā ierīcē apkopot virkni apakšprocesu vai pavedienu, kuriem jāpalaiž pārējais lietojumprogrammas kods. Tas pasliktinās jūsu lietojumprogrammas veiktspēju visiem lietotājiem. Lieliski būtu šos darbus izpildīt citā vai daudzās citās mašīnās.

Lieliska Python bibliotēka šim uzdevumam ir RQ , ļoti vienkārša, bet spēcīga bibliotēka. Izmantojot bibliotēku, jūs vispirms ievietojat funkciju un tās argumentus. Šī marinēti gurķi funkciju izsaukuma attēlojums, kas pēc tam tiek pievienots a Redis sarakstu. Darba iesaukšana ir pirmais solis, bet pagaidām neko nedos. Mums ir nepieciešams arī vismaz viens darbinieks, kurš uzklausa šo darba rindu.

jenkins vs gitlab ci

Pirmais solis ir instalēt un palaist savā datorā Redis serveri vai piekļūt esošam Redis serverim. Pēc tam esošajā kodā ir veiktas tikai dažas nelielas izmaiņas. Vispirms mēs izveidojam RQ rindas gadījumu un nododam tam Redis servera instanci no redis-py bibliotēka . Tad tā vietā, lai tikai izsauktu mūsu | _+_ | metodi, mēs zvanām | _+_ |. Savākšanas metode kā pirmo argumentu ņem funkciju, pēc tam visi citi argumenti vai atslēgvārdu argumenti tiek nodoti šai funkcijai, kad darbs tiek faktiski izpildīts.

zebra lp 2824 plus tukšu uzlīmju drukāšana

Pēdējais solis, kas mums jādara, ir sākt dažus darbiniekus. RQ nodrošina ērtu skriptu, lai palaistu darbiniekus noklusējuma rindā. Vienkārši skrien | _+_ | termināļa logā, un darbinieks sāks klausīties noklusējuma rindā. Lūdzu, pārliecinieties, vai jūsu pašreizējais darba direktorijs ir tāds pats kā skriptu atrašanās vieta. Ja vēlaties klausīties citu rindu, varat palaist | _+_ | un tā noklausīsies šo nosaukto rindu. Lieliska lieta par RQ ir tā, ka, kamēr jūs varat izveidot savienojumu ar Redis, jūs varat vadīt tik daudz darbinieku, cik vēlaties, tik daudzās dažādās mašīnās, cik vēlaties; tāpēc, palielinoties lietojumprogrammai, to ir ļoti viegli palielināt. Šeit ir RQ versijas avots:

Authorization

Tomēr RQ nav vienīgais Python darba rindas risinājums. RQ ir viegli lietojams, un tas ārkārtīgi labi aptver vienkāršus lietošanas gadījumus, bet, ja ir vajadzīgas papildu iespējas, citi Python 3 rindas risinājumi (piemēram, Selerijas ) Var izmantot.

Python multithreading vs Multiprocessing

Ja jūsu kods ir saistīts ar IO, jums noderēs gan daudzapstrāde, gan daudzpavedieni Python. Daudzapstrādi ir vieglāk iemest, nekā vītņot, bet tai ir lielāka atmiņas pieskaitāmā summa. Ja jūsu kods ir saistīts ar CPU, visticamāk, labāka izvēle būs daudzapstrāde, it īpaši, ja mērķa mašīnai ir vairāki kodoli vai CPU. Tīmekļa lietojumprogrammām un gadījumos, kad darbs ir jāsadala vairākās mašīnās, RQ jums būs labāks.

Saistīts: Kļūsti progresīvāks: izvairies no 10 visbiežāk sastopamajām kļūdām, ko pieļauj Python programmētāji ] ( https://www.toptal.com/python/top-10-mistakes-that-python-programmers-make ) https://www.toptal.com/python/top-10-mistakes-that-python-programmers-make ))

Atjaunināt

Python | _+_ |

Kopš Python 3.2 kaut kas jauns, kas sākotnējā rakstā netika skarts, ir pakotne | _+_ |. Šī pakete nodrošina vēl vienu veidu, kā izmantot vienlaicīgumu un paralēlismu ar Python.

Sākotnējā rakstā es minēju, ka Python daudzapstrādes moduli būtu vieglāk ievietot esošajā kodā nekā pavedienu moduli. Tas bija tāpēc, ka Python 3 vītņu modulim bija nepieciešama | _+_ | apakšklasēšana klasē, kā arī izveidojot | _+_ | pavedieniem, lai uzraudzītu darbu.

Izmantojot a vienlaicīgas. nākotnes. ThreadPoolExecutor padara Python pavedienu parauga kodu gandrīz identisku daudzapstrādes modulim.

import json import logging import os from pathlib import Path from urllib.request import urlopen, Request logger = logging.getLogger(__name__) types = {'image.jpeg'>this GitHub repository .

Concurrency and Parallelism in Python: Threading Example

Threading is one of the most well-known approaches to attaining Python concurrency and parallelism. Threading is a feature usually provided by the operating system. Threads are lighter than processes, and share the same memory space.

In this Python threading example, we will write a new module to replace single.py

Tagad, kad visi šie attēli ir lejupielādēti ar mūsu Python | _+_ |, mēs varam tos izmantot, lai pārbaudītu ar CPU saistītu uzdevumu. Mēs varam izveidot visu attēlu sīktēlu versijas gan ar vienu pavedienu, gan viena procesa skriptu, un pēc tam pārbaudīt uz daudzprocesu balstītu risinājumu.

Mēs gatavojamies izmantot Spilvens bibliotēku, lai apstrādātu attēlu lielumu.

Šeit ir mūsu sākotnējais skripts.

DownloadWorker

Šeit ir diezgan daudz ko izpakot. Sāksim ar programmas galveno ieejas punktu. Pirmā jaunā lieta, ko mēs darām ar asyncio moduli, ir iegūt notikumu ciklu. Notikumu cilpa apstrādā visu asinhrono kodu. Pēc tam cilpa tiek palaista, līdz tā ir pabeigta un nokārtota | _+_ | funkciju. Galvenā definīcijā ir jauna sintakse: | _+_ |. Jūs arī pamanīsit | _+_ | un | _+_ |.

mywifiext iestatīšana ir veiksmīga

Async/gaidīšanas sintakse tika ieviesta PEP492 . | _+_ | sintakse iezīmē funkciju kā a korutīns . Iekšēji korutīnu pamatā ir Python ģeneratori, taču tie nav gluži viens un tas pats. Korutīni atgriež korutīnu objektu līdzīgi tam, kā ģeneratori atgriež ģeneratora objektu. Kad esat ieguvis korutīnu, tā rezultātus iegūstat, izmantojot | _+_ | izteiksme. Kad korutīns izsauc | _+_ |, korutīna izpilde tiek apturēta, līdz tiek pabeigts gaidāmais. Šī apturēšana ļauj pabeigt citus darbus, kamēr korutīns ir apturēts, gaidot kādu rezultātu. Parasti šis rezultāts būs sava veida I/O, piemēram, datu bāzes pieprasījums vai mūsu gadījumā HTTP pieprasījums.

| _+_ | funkcija bija diezgan būtiski jāmaina. Iepriekš mēs paļāvāmies uz | _+_ | lai paveiktu lielāko daļu darba, lasot attēlu mūsu vietā. Tagad, lai mūsu metode varētu pareizi darboties ar asinhronās programmēšanas paradigmu, esam ieviesuši | _+_ | cilpa, kas vienlaikus lasa attēla gabalus un aptur izpildi, gaidot I/O pabeigšanu. Tādējādi notikumu cilpa var lejupielādēt dažādus attēlus, jo katram no tiem lejupielādes laikā ir pieejami jauni dati.

Ir jābūt vienam - vēlams tikai vienam - acīmredzamam veidam, kā to izdarīt

Kamēr Python zen stāsta, ka vajadzētu būt vienam acīmredzamam veidam, kā kaut ko darīt, Python ir daudz veidu, kā mūsu programmās ieviest vienlaicīgumu. Labākā izvēlētā metode būs atkarīga no jūsu konkrētā lietošanas gadījuma. Asinhronā paradigma ir labāk pielāgojama darba slodzei ar augstu vienlaicīgumu (piemēram, tīmekļa serverim), salīdzinot ar pavedienu vai vairāku apstrādi, taču, lai gūtu pilnīgu labumu, jūsu kodam (un atkarībām) ir jābūt asinhronam.

Cerams, ka šajā rakstā iekļautie un atjauninātie Python pavedienu piemēri norādīs pareizo virzienu, lai jums būtu ideja par to, kur meklēt Python standarta bibliotēku, ja nepieciešams savās programmās ieviest vienlaicīgumu.

Sākotnēji publicēja Mārks KKURDIJS plkst * * toptal.com

amazon python intervijas jautājumi

================================================ == ==========================

Paldies, ka izlasījāt: heart: Ja jums patika šī ziņa, kopīgojiet to ar visiem saviem programmēšanas draugiem! Sekojiet man Facebook | Twitter

Uzzināt vairāk

Pabeigt Python Bootcamp: pārejiet no nulles uz varoni programmā Python 3

Pabeigt Python meistarklasi

Uzziniet Python, izveidojot blokķēdi un kriptovalūtu

Python un Django Full Stack Web Developer Bootcamp

Python Bible ™ | Viss, kas jums jāprogrammē Python

Mācīties Python datu analīzei un vizualizācijai

Python finanšu analīzei un algoritmiskai tirdzniecībai

Mūsdienu Python 3 sāknēšanas nometne

#Pitons

www.toptal.com

Python vairāku pavedienu un daudzprocesu apmācība

Diskusijās, kurās tiek kritizēts Python, bieži tiek runāts par to, cik grūti ir izmantot Python daudzšķiedru darbam, rādot ar pirkstiem uz tā saukto globālo tulku ...