由於python線程的性能問題,在python中使用多線程運行代碼常常不能達到預期的效果。而有些時候咱們的邏輯中又須要開更高的併發,或者簡單的說,就是讓咱們的代碼跑的更快,在一樣時間內執行更多的有效邏輯、減小無用的等待。gevent就是一個如今很火、支持也很全面的python第三方協程庫。
gevent是python的一個併發框架,以微線程greenlet爲核心,使用了epoll事件監聽機制以及諸多其餘優化而變得高效。並且其中有個monkey類,將現有基於Python線程直接轉化爲greenlet(相似於打patch)。在運行時的具體流程大概就是:
當一個greenlet遇到IO操做時,好比訪問網絡/睡眠等待,就自動切換到其餘的greenlet,等到IO操做完成,再在適當的時候切換回來繼續執行。因爲IO操做很是耗時,常常使程序處於等待狀態,有了gevent爲咱們自動切換協程,就保證總有greenlet在運行,而不是等待IO。同時也由於只有一個線程在執行,會極大的減小上下文切換的成本。python
#!/bin/python #coding = UFT-8 import gevent from gevent import socket from gevent import monkey; monkey.patch_all() import sys,os,wget import urllib2 import subprocess def download(url): ###下爲判斷url是否存在。。#### try: url_opener = urllib2.urlopen(url) except: print 'open url error' return if url_opener.code!=200: print 'return code is:%d'%(url_opener.code) return if not url_opener.headers.has_key('Content-Length'): print 'no content length' return file_name = url[url.rfind('/')+1:] #wget.download(url) status_subprocess = subprocess.call('wget -c %s' %(url),shell=True) if status_subprocess == 0: print '[%s]:download complete!' % (file_name) else: print '[%s]:download failed !' % (file_name) list_file_name = sys.argv[1] print list_file_name print sys.argv file1 = open(list_file_name,'r') s = file1.read() #print s apkurl_list = s.split() #print apkurl_list if __name__=='__main__': argc = len(sys.argv) if argc<2: print 'usage:%s <url> [url...]' % (sys.argv[0]) sys.exit(-1) #jobs = [gevent.spawn(download,url) for url in sys.argv[1:]] jobs = [gevent.spawn(download,url) for url in apkurl_list] gevent.joinall(jobs, timeout=600)
wget -c url -c:爲斷點續傳模式 ,ctrl+C是殺不掉,只kill -QUIT 或者跑完
[root@silence tmp]# cat apk.list http://axk.cdn.lx7.com/2915/sxxxxxxxxxxxxxxb7.apk http://cdnxxx.ofxme.net/axxxets/Axx346/mjxxxxx03.apk
[root@silence tmp]# python apkbingxingdownload.py apk.list