Greenlet Vs. Ағымдар

Мен гевенты мен көкөністерге жаңадан келдім. Мен олармен жұмыс істеу туралы жақсы құжаттарды тауып алдым, бірақ ешкім мені қалай және қашан пайдалану керектігін түсіндірді!

  • Олар шынымен жақсы нәрсе?
  • Прокси-серверлерде оларды пайдалануға бола ма?
  • Неге ағынсыз?

Мен көбінесе бірлескен бағдарламалардың бірі болса, біз олармен қатарластықты қалай қамтамасыз ете алатындығына сенімдімін.

88
21 марта '13 в 22:49 2013-03-21 22:49 Рш 21- наурызда сағат 13-те тағайындалды 2013-03-21 22:49
@ 3 жауаптар

Жасылдар параллелизмді емес, параллельдікті қамтамасыз етеді. параллельдік код кодекс басқа кодтан тәуелсіз жұмыс істей алады. Параллелизм - мезгілде кодты орындау. Параллелизм әсіресе пайдаланушының кеңістігінде үлкен жұмыс қажет болғанда пайдалы және әдетте ауыр процессор болып табылады. қатарластық параллельді түрлі бөліктерді жоспарлауға және теңшеуге мүмкіндік беретін ақаулықтарды жою үшін пайдалы.

Greenlet желілік бағдарламалауда шынымен жарқырайды, егер бір розеткамен өзара әрекеттесу басқа розеткалармен өзара байланыссыз қарамастан жүзеге асады. Бұл параллельді классикалық мысал. Әр жасыл өз контекстінде жұмыс істеген сайын, ағынсыз синхронды API пайдалануды жалғастыра аласыз. Бұл жақсы, себебі жіптер виртуалды жады мен ядро ​​шығындарына байланысты өте қымбат, сондықтан жұппен қол жеткізе алатын параллельділік әлдеқайда төмен. Сонымен қатар, Python-дағы тақырыптар GIL арқасында әдеттегіден қымбатырақ және шектеледі. Бақылауға арналған баламалар, әдетте, Twisted, libevent, libuv, node.js, және т.б. сияқты жобаларда қолданылады, онда барлық кодыңыз бірдей орындау контекстіне ие және оқиғалар өңдегіштерін тіркейді.

Прокси серверді жазу үшін жасыл (мысалы, желілік қолдау арқылы, мысалы, gevent арқылы) жасанды пайдалану өте жақсы идея. Өтінімді өңдеу дербес түрде орындалуы мүмкін және сол сияқты жазылуы керек.

Жасылдандыру бұрын берген себептерім бойынша параллельдікті қамтамасыз етеді. параллелизм емес. Оқиғалардың тіркелуін жасыру және әдетте ағымдағы ағынды блоктайтын қоңырауларға жоспарлау арқылы, мысалы, gevent сияқты жобалар асинхронды API өзгертпей және жүйеңіздің әлдеқайда төмен шығындарын талап етпестен осы сәттен бастап анықталады.

139
24 марта '13 в 10:47 2013-03-24 10:47 жауапты Мэтт Доменер 24 наурыз 13 сағат 10:47 2013-03-24 10:47

@Max жауабын қабылдау және масштабтау үшін оған маңызды мәнді қосу арқылы айырмашылықты көре аласыз. Мен мұны URL-мекен-жайларын төмендегідей толтырып өзгерту арқылы жасадым:

 URLS_base = ['www.google.com', 'www.example.com', 'www.python.org', 'www.yahoo.com', 'www.ubc.ca', 'www.wikipedia.org'] URLS = [] for _ in range(10000): for url in URLS_base: URLS.append(url) 

Бірнеше процессорлармен нұсқадан бас тартуға мәжбүр болдым, өйткені 500-ге дейін болдым; бірақ 10,000 иерациямен:

border=0
 Using gevent it took: 3.756914 ----------- Using multi-threading it took: 15.797028 

Осылайша, gevent көмегімен I / O елеулі айырмашылық бар екенін көре аласыз

17
07 марта '15 в 0:16 2015-03-07 00:16 жауап 07 маусым 2015 жылы 0:16 2015-03-07 00:16

Талдау өте қызықты. Жасыл және многопроцессорлық бассейндерді многоботалармен салыстырғанда салыстыруға болатын код:

 import gevent from gevent import socket as gsock import socket as sock from multiprocessing import Pool from threading import Thread from datetime import datetime class IpGetter(Thread): def __init__(self, domain): Thread.__init__(self) self.domain = domain def run(self): self.ip = sock.gethostbyname(self.domain) if __name__ == "__main__": URLS = ['www.google.com', 'www.example.com', 'www.python.org', 'www.yahoo.com', 'www.ubc.ca', 'www.wikipedia.org'] t1 = datetime.now() jobs = [gevent.spawn(gsock.gethostbyname, url) for url in URLS] gevent.joinall(jobs, timeout=2) t2 = datetime.now() print "Using gevent it took: %s" % (t2-t1).total_seconds() print "-----------" t1 = datetime.now() pool = Pool(len(URLS)) results = pool.map(sock.gethostbyname, URLS) t2 = datetime.now() pool.close() print "Using multiprocessing it took: %s" % (t2-t1).total_seconds() print "-----------" t1 = datetime.now() threads = [] for url in URLS: t = IpGetter(url) t.start() threads.append(t) for t in threads: t.join() t2 = datetime.now() print "Using multi-threading it took: %s" % (t2-t1).total_seconds() 

мына нәтижелер:

 Using gevent it took: 0.083758 ----------- Using multiprocessing it took: 0.023633 ----------- Using multi-threading it took: 0.008327 

Менің ойымша, бұл жасыл көпшілікке арналған кітапханаға қарағанда GIL-ке байланысты емес екенін айтады. Сонымен қатар, Greenlet құжаты желі операциялары үшін арналған деп айтады. Интенсивті желілер үшін, ағындарды ауыстыру әдемі болып табылады және сіз многопоточный тәсіл өте жылдам екенін көре аласыз. Сондай-ақ ол әрдайым ресми питон кітапханаларын пайдаланғысы келеді; Мен жасыл терезені терезеге орнатуға тырысып, DLL тәуелділік мәселесіне жүгірдім, сондықтан мен осы linux vm тестін орындадым. Alway кез-келген машинада жұмыс істейтініне үміттенетін кодты жазуға тырысады.

10
13 дек. Жауап 13 желтоқсанға дейін беріледі. 2014-12-13 02:27 '14 уақытта 2:27 2014-12-13 02:27

тегтері туралы басқа сұрақтар немесе Сұрақ қою