pythongevent安裝
A. centos6.5 安裝goAgent 使用python需要安裝gevent但是安裝後仍沒用
gevent 還需要先裝 greenlet 和 Cython 才能奏效。
B. windows下怎麼安裝Gevent
使用gevent,可以對並發多個http請求的爬蟲程序進行很好的優化, 缺點是,安裝相對麻煩,這個包依賴於libevent,在windows下面用easy_install直接安裝是不行的,必須用源代碼包
wget http://pypi.python.org/packages/source/g/gevent/gevent-0.13.8.tar.gz
tar zxvf gevent-0.13.8.tar.gz
cd gevent
裡面有個fetch_libevent.py 用來幫你下載libevent依賴
python fetch_libevent.py
python setup.py build
python setup.py install
這樣可以安裝成功,如果還不行,只能使用大殺器了windows下安裝python模塊的終極解決方案。
C. python怎麼導入模塊gevent
Python通過yield提供了對協程的基本支持,但是不完全。而第三方的gevent為Python提供了比較完善的協程支持。
gevent是第三方庫,通過greenlet實現協程,其基本思想是:
當一個greenlet遇到IO操作時,比如訪問網路,就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。由於IO操作非常耗時,經常使程序處於等待狀態,有了gevent為我們自動切換協程,就保證總有greenlet在運行,而不是等待IO。
D. python的安裝包最後一直初始化怎麼解決
當遇到無法導入某個python模塊時,可能會是沒有安裝某個模塊,也有可能是某模塊在載入過程中失敗,也有可能是陷入了循環導入的問題。本文詳細解釋了這個問題。
1. 模塊未安裝或者路徑不對
ImportError: No mule named myMole
有兩種可能,一是該模塊沒有安裝,一般可以用
pip install %mole_name%
來解決。注意有時候模塊安裝包名並不等於要導入的模塊名。這種情況下可以通過pip search | list命令來嘗試找到正確的包。
另一種情況就是包雖然安裝了,但當前運行的程序載入的路徑有錯。python運行時將從以下位置嘗試載入python moles:
* 當前目錄
* 環境變數$PYTHONPATH所指示的值,這是一個由「:」分隔的字元串,各個子字元串都是文件系統的一個路徑。
* 標准庫目錄,如dist-site-packages下的模塊。
* 在.pth文件中指定的路徑,如果存在.pth文件的話。
可以使用以下方式來查看python運行時的包含路徑:
?
12
import sysprint(sys.path)
在運行出錯的腳本裝頭部加上這一段代碼,然後在控制台中查看列印出來的python類庫路徑,檢查安裝包是否已包含在上述路徑中。
***可以通過下面的方式將未包含在路徑中的模塊臨時包含進來:***
sys.path.append("path/to/mole")
另外,還可以在shell窗口中查看當前的python包含路徑:
echo $PYTHONPATH
2. 無法導入已存在的模塊
如果要導入的模塊包含了native代碼,並且native代碼載入(初始化)失敗時,就會導致這種錯誤。使用ssl,
gevent等涉及native的模塊時,如果對應的native程序並未安裝,則會出現這樣的錯誤。
另一種錯誤情況是,使用相對路徑導入時,父模塊還未導入成功。見下面的代碼:
?
12345
main.pymypackage/ __init__.pymymole.pymyothermole.py
mymole.py如下所示:
?
123456789101112
#!/usr/bin/env python3 # Exported functiondef as_int(a): return int(a) # Test function for mole def _test(): assert as_int('1') == 1 if __name__ == '__main__': _test()
以及myothermole代碼如下所示:
?
1234567891011121314
#!/usr/bin/env python3 from .mymole import as_int # Exported functiondef add(a, b): return as_int(a) + as_int(b) # Test function for mole def _test(): assert add('1', '1') == 2 if __name__ == '__main__': _test()
如果執行mypackage/myothermole,則會報以下錯誤:
Traceback (most recent call last):
File "myothermole.py", line 3, in
<mole>
from .mymole import as_int
SystemError: Parent mole
'' not loaded, cannot perform relative import
[這篇文章](#Relative imports in
Python 3)給出了更詳細的解答。
3. 循環導入
這種錯誤稱之為"circular (or cyclic) imports"。是python獨有的一種導入錯誤,在象java這樣的語言中就不存在。
假設有如下兩個文件,a.py和b.py:
?
1234567
#a.pyprint "a in"import sysprint "b imported: %s" % ("b" in sys.moles, )import bprint "a out"print b.x
以及:
?
12345
#b.pyprint "b in"import aprint "b out"x = 3
執行python a.py,將得到以下結果:
?
123456789101112131415
$ python a.pya in b imported: Falseb ina inb imported: Truea outTraceback (most recent call last): File "a.py", line 4, in <mole> import b File "/home/shlomme/tmp/x/b.py", line 2, in <mole> import aFile "/home/shlomme/tmp/x/a.py", line 7, in <mole> print b.xAttributeError: 'mole' object has no attribute 'x'
出現這種情況的原因是產生了循環導入。循環導入,以及在導入過程中python進行了加鎖操作,最終導致在模塊b未導入完成時就引用了其中的名字。
判斷導入錯誤是否是因為循環導入引起的,主要看堆棧中是否出現兩次重復的導入。比如上述堆棧中a.py出現兩次,因此可以判斷是這個文件引起的循環導入。
要解決這個問題,可以把模塊看成一種資源,對所有要引入的模塊進行編號,再按靜態資源排序法順次導入,就可以避免循環導入。
E. gevent怎麼編譯
在gevent中主要使用Greenlet,給Python提供一個輕量級的協同程序,作為一個C的擴展模
塊.Greenlets主程序運行的所有系統進程是合理安排的.
這不同於任何multiprocessing或者multithreading提供的庫和POSIX線程,這是真正的並行多處理器或多線程庫提供真正的並
行結構
首先感謝https://maskv.com/technology/192.html作者給我的幫助我參考老方法編譯gevent1.0rc2成功但是無法運行Goagent最新版只能運行2.17原因就是缺少python2.7的支持現在博主給出啦方法搬過來方便大家
Tomato中python2.7+gevent1.0rc2環境的搭建
之前因為沒有搜索到在Tomato中編譯安裝gevent的教程,就自己琢磨出來Tomato中python2.6+gevent0.13.8環境的搭建方法(點擊這里查看),
文章發布之後收到了眾多的反饋。雖然Python官網當中的gevent最新版本為0.13.8,但Github上的gevent源碼已經更新到了
1.0rc2,最新版的Goagent本地客戶端也集成的是gevent1.0rc2,在整合了一些反饋之後,在自己的路由器上成功更新了python和
gevent。
首先卸載路由當中的python2.6及其相關組件,運行:
ipkg -force-removal-of-dependent-packages remove python26
rm -rf /opt/local/lib/python2.6 #若掛載路徑非/opt請自行修改
rm -rf /opt/lib/python2.6
之後更新、安裝所需要的依賴包:
ipkg update
ipkg upgrade
ipkg install busybox buildroot make grep openssl openssl-dev libuclibc++ wget-ssl python27 py27-setuptools
安裝完成之後,我們要修復幾個py27-setuptools當中的小錯誤。
首先easy_install的安裝路徑莫名其妙的指向了python2.5,不知是否只有我遇到了這個問題。修改 /opt/lib/python2.7/distutils/distutils.cfg 文件,將
1
site-dirs = /opt/local/lib/python2.5/site-packages
修改為
1
site-dirs = /opt/local/lib/python2.7/site-packages
其次easy_install的安裝臨時目錄指向了/tmp目錄,會造成安裝某些組件時tmp剩餘空間不足而導致的安裝失敗,我們要手動將其指定到掛載的U盤當中。
在/opt中創建tmp文件夾,修改 /opt/lib/python2.7/site-packages/setuptools/command/easy_install.py 文件,找到412行:
1
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
將其修改為:
1
tmpdir = tempfile.mkdtemp(prefix="easy_install-",dir="/opt/tmp")
然後就可以使用easy_install安裝greenlet與cython了(此步驟花費時間奇長無比):
easy_install-2.7 greenlet
easy_install-2.7 cython
ln -s /opt/local/bin/cygdb /opt/bin/cygdb
ln -s /opt/local/bin/cython /opt/bin/cython
之後下載gevent:
cd /opt
/opt/bin/wget https://github.com/downloads/Sit ... event-1.0rc2.tar.gz --no-check-certificate
tar zxvf gevent-1.0rc2.tar.gz
cd gevent-1.0rc2
直接編譯會報錯,因為使用了mips2的sync指令,在Goagent的issues上找到了答案。心得編譯前記得開啟虛擬內存
修改 /libev/ev.c 文件,找到604行的:參考https://code.google.com/p/goagent/issues/detail?id=7823
1
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
修改為:
#define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0": : :"memory")
執行
python2.7 setup.py install
下載並安裝pyOpenSSL
cd /opt
wget http://pypi.python.org/packages/source/p/pyOpenSSL/pyOpenSSL-0.12.tar.gz
tar zxvf pyOpenSSL-0.12.tar.gz
cd pyOpenSSL-0.12
python2.7 setup.py install
安裝結束之後,運行Goagent可能會提示.python-eggs錯誤,我們可以手動指定緩存目錄。
修改Goagent的proxy.py文件,在:
1
import os
下一行添加:
1
os.environ['PYTHON_EGG_CACHE'] = '/opt/.python-eggs'
或者可以將 gevent-1.0rc2-py2.7-linux-mips.egg 解包:
cd /opt/local/lib/python2.7/site-packages
mv gevent-1.0rc2-py2.7-linux-mips.egg gevent-1.0rc2-py2.7-linux-mips.egg.zip
mkdir gevent-1.0rc2-py2.7-linux-mips.egg
cd gevent-1.0rc2-py2.7-linux-mips.egg
unzip /opt/local/lib/python2.7/site-packages/gevent-1.0rc2-py2.7-linux-mips.egg.zip
再次運行Goagent,應該不會再有錯誤提示了。
F. python解釋器中gevent出現錯誤怎麼解決
解決方法:重新安裝gevent以及依賴
pip3 install -U --force-reinstall --no-binary :all: gevent
G. python協程gevent怎麼用
在學習gevent之前,你肯定要知道你學的這個東西是什麼。
官方描述gevent
gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of the libev event loop.
翻譯:gevent是一個基於協程的Python網路庫。我們先理解這句,也是這次學習的重點——協程。
wiki描述協程
與子常式一樣,協程也是一種程序組件。相對子常式而言,協程更為一般和靈活,但在實踐中使用沒有子常式那樣廣泛。子常式的起始處是惟一的入口點,一旦退出即完成了子常式的執行,子常式的一個實例只會返回一次;協程可以通過yield來調用其它協程。通過yield方式轉移執行權的協程之間不是調用者與被調用者的關系,而是彼此對稱、平等的。協程允許多個入口點,可以在指定位置掛起和恢復執行。
沒看懂?沒關系,我也沒看懂,不過算是有點線索:子常式。
子常式
過程有兩種,一種叫子常式(Subroutine),通常叫Sub;另一種叫函數(Function)。底層實現機制是一樣的,區別在於,Sub只執行操作,沒有返回值;Function不但執行操作,並且有返回值。用過VB的應該會比較清楚這點。(原諒我用了網路)說到底子常式就是過程,我們一般叫它函數。
說到函數,我就想吐槽了,不明白為什麼要叫函數。很多時候我們寫一個函數是為了封裝、模塊化某個功能,它是一個功能、或者說是一個過程。因為它包含的是類似於流程圖那樣的具體邏輯,先怎樣做,然後怎樣做;如果遇到A情況則怎樣,如果遇到B情況又怎樣。個人覺得還是叫過程比較好,叫做函數就讓人很糾結了,難道因為回歸到底層還是計算問題,出於數學的角度把它稱為函數?這個略坑啊!為了符合大家的口味,我還是稱之為函數好了(其實我也習慣叫函數了%>_
講到函數,我們就往底層深入一點,看看下面的代碼:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def a():
print "a start"
b()
print "a end"
def b():
print "b start"
c()
print "b end"
def c():
print "c start"
print "c end"
if __name__ == "__main__":
a()
a start
b start
c start
c end
b end
a end
對於這樣的結果大家肯定不會意外的。每當函數被調用,就會在棧中開辟一個棧空間,調用結束後再回收該空間。
假設一個這樣的場景:有個講台,每個人都可以上去發表言論,但是每次講台只能站一個人。現在a在上面演講,當他說到「大家好!」的時候,b有個緊急通知要告訴大家,所以a就先下來讓b講完通知,然後a再上講台繼續演講。如果用函數的思想模擬這個問題,堆棧示意圖是這樣的:
那什麼東西有這樣的能力呢?我們很快就可以想到進程、線程,但是你真的想使用進程、線程如此重量級的東西在這么簡單的程序上嗎?野蠻的搶占式機制和笨重的上下文切換!
還有一種程序組件,那就是協程。它能保留上一次調用時的狀態,每次重新進入該過程的時候,就相當於回到上一次離開時所處邏輯流的位置。協程的起始處是第一個入口點,在協程里,返回點之後是接下來的入口點。協程的生命期完全由他們的使用的需要決定。每個協程在用yield命令向另一個協程交出控制時都盡可能做了更多的工作,放棄控制使得另一個協程從這個協程停止的地方開始,接下來的每次協程被調用時,都是從協程返回(或yield)的位置接著執行。
從上面這些你就可以知道其實協程是模擬了多線程(或多進程)的操作,多線程在切換的時候都會有一個上下文切換,在退出的時候將現場保存起來,等到下一次進入的時候從保存的現場開始,繼續執行。
看下協程是怎樣實現的:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import random
from time import sleep
from greenlet import greenlet
from Queue import Queue
queue = Queue(1)
@greenlet
def procer():
chars = ['a', 'b', 'c', 'd', 'e']
global queue
while True:
char = random.choice(chars)
queue.put(char)
print "Proced: ", char
sleep(1)
consumer.switch()
@greenlet
def consumer():
global queue
while True:
char = queue.get()
print "Consumed: ", char
sleep(1)
procer.switch()
if __name__ == "__main__":
procer.run()
consumer.run()
應用場景
我們一直都在大談協程是什麼樣一個東西,卻從沒有提起協程用來幹嘛,這個其實大家分析一下就能夠知道。從上面的生產者——消費者問題應該能看出,它分別有兩個任務,假設交給兩個人去執行,但每次只能允許一個人行動。當緩沖區滿的時候,生產者是出於等待狀態的,這個時候可以將執行任務的權利轉交給消費者,當緩沖區空得時候,消費者是出於等待狀態的,這個時候可以將執行任務的權利轉交給生產者,是不是很容易聯想到多任務切換?然後想到線程?最後想到高並發?
但同學們又會問,既然有了線程為什麼還要協程呢?因為線程是系統級別的,在做切換的時候消耗是特別大的,具體為什麼這么大等我研究好了再告訴你;同時線程的切換是由CPU決定的,可能你剛好執行到一個地方的時候就要被迫終止,這個時候你需要用各種措施來保證你的數據不出錯,所以線程對於數據安全的操作是比較復雜的。而協程是用戶級別的切換,且切換是由自己控制,不受外力終止。
總結
協程其實模擬了人類活動的一種過程。例如:你准備先寫文檔,然後修復bug。這時候接到電話說這個bug很嚴重,必須立即修復(可以看作CPU通知)。於是你暫停寫文檔,開始去填坑,終於你把坑填完了,你回來寫文檔,這個時候你肯定是接著之前寫的文檔繼續,難道你要把之前寫的給刪了,重新寫?這就是協程。那如果是子常式呢?那你就必須重新寫了,因為退出之後,棧幀就會被彈出銷毀,再次調用就是開辟新的棧空間了。
總結:協程就是用戶態下的線程,是人們在有了進程、線程之後仍覺得效率不夠,而追求的又一種高並發解決方案。為什麼說是用戶態,是因為操作系統並不知道它的存在,它是由程序員自己控制、互相協作的讓出控制權而不是像進程、線程那樣由操作系統調度決定是否讓出控制權。
H. 在樹莓派上安裝python的gevent失敗不是此平台支持的車輪
你安裝的不是Arm架構的wheel,搜索一下python for arm或python for arm64來了解一下。
I. Win8.1 64位系統,python3.4 怎麼安裝gevent成功後不能用
windows安裝這個太麻煩了:①先裝VS,裡面要勾選上"編程語言"包,這樣就能找到vsvarsall.bat了
②然而scrapy還依賴其他一些包,所以還要安裝Lxml。
下載完以後到命令行輸入:pip install lxml-3.5.0-cp35-none-win_amd64.whl(或者下載的32位的名字就變一下)③再到命令行:pip install scrapy,安裝成功了TT
令:我的是win10系統,python3.5。本人小白一隻><
參考資料:安裝指南 — Scrapy 0.24.1 文檔
①然而後來發現還是用不了,跑不了他的Demo。提示沒有"_win32stdio"。所以上StackOverflow查了一下,說Python3.5沒有這個庫。後來也發現人家Scrapy官網說不支持Python3。
②所以我又安裝了Python2.7,然後pip install scrapy的時候,他又提示要裝Visual C++ Compiler for Python 2.7。然而我看了一下這個的說明,不支持win10(win8.1應該可以吧)。反正後續我就沒再搞了TT
③所以我就轉戰Ubuntu了。因為自帶Python2.7.6,所以不到半小時就搞定了。Scrapy給的Demo也能跑了。
結論:所以還是別用windows了
J. python gevent怎麼安裝
gevent是第三方庫,從https://pypi.python.org/pypi/gevent/#downloads下載安裝,在下載文件目錄下,使用 命令:pip install xxx.whl 安裝即可。