记前
最近项目上线,终于迎来了一个双休日,宅在家里眼瞅着肚子上的赘肉一圈一圈,实在不敢相信当年我是那个“怎么吃都不长肉”的瘦身少年。瘦子没法理解胖子的痛,瘦子终于有了同感。于是乎,待到晚上9点半开始了跑步,拉力器,仰卧起坐等一系列瘦身塑形锻炼。大汗淋漓地冲了一个澡,爽!
正文
用Python也有两年了,很少在生产中用到线程来设计程序,最近看到两篇不错的文章,准备自己记录一下。原文在这里:
插曲
MD,写到这里接到老大地bug报告,修完了一个SB地Bug回来继续。
单进程单线程服务器(无实用价值)
(webserver_single_thread.py) download
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
def sequential ( port ):
s = socket . socket ()
s . bind (( '0.0.0.0' , port ))
s . listen ( 500 )
while True :
cli , addr = s . accept ()
handle_request ( cli , time . sleep )
def handle_request ( s , sleep ):
try :
s . recv ( 1024 )
sleep ( 0.1 )
s . send ( '''http/1.0 200 OK
Hello World! ''' )
s . shutdown ( socket . SHUT_WR )
print '.' ,
except Exception , ex :
print ex
finally :
sys . stdout . flush ()
s . close ()
if __name__ == '__main__' :
sequential ( 4444 )
批注:没有人会用单线程做服务器,除非你是像我现在一样用来练习。
单进程多线程服务器(无实用价值)
(webserver_multi_threads.py) download
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
32
33
34
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
import threading
def threads ( port ):
s = socket . socket ()
s . bind (( '0.0.0.0' , port ))
s . listen ( 500 )
while True :
cli , addr = s . accept ()
t = threading . Thread ( target = handle_request , args = ( cli , time . sleep ))
t . daemon = True
t . start ()
def handle_request ( s , sleep ):
try :
s . recv ( 1024 )
sleep ( 0.1 )
s . send ( '''http/1.0 200 OK
Hello World! ''' )
s . shutdown ( socket . SHUT_WR )
print '.' ,
except Exception , ex :
print ex
finally :
sys . stdout . flush ()
s . close ()
if __name__ == '__main__' :
threads ( 4444 )
批注:多线程之间的切换也是很耗资源的事情,所以就有了下面的线程池。
单进程线程池服务器(无实用价值)
(webserver_thread_pool.py) download
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
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
import threading
import Queue
def server ( port , N ):
s = socket . socket ()
s . bind (( '0.0.0.0' , port ))
s . listen ( 500 )
q = Queue . Queue ()
for x in range ( N ):
t = threading . Thread ( target = thread_worker , args = ( q , ))
t . daemon = True
t . start ()
print 'Ready and waiting with %d threads on port %d ' % ( N , port )
while True :
cli , addr = s . accept ()
q . put ( cli )
def thread_worker ( q ):
sock = q . get ()
handle_request ( sock , time . sleep )
def handle_request ( s , sleep ):
try :
s . recv ( 1024 )
sleep ( 0.1 )
s . send ( '''http/1.0 200 OK
Hello World! ''' )
s . shutdown ( socket . SHUT_WR )
print '.' ,
except Exception , ex :
print ex
finally :
sys . stdout . flush ()
s . close ()
if __name__ == '__main__' :
server ( 4444 , 5 )
批注:受到Python的GIL的制约。
单进程gevent服务器(无实用价值)
(webserver_gevent.py) download
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
32
33
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
import gevent
from gevent import socket
def server ( port ):
s = socket . socket ()
s . bind (( '0.0.0.0' , port ))
s . listen ( 500 )
while True :
cli , addr = s . accept ()
gevent . spawn ( handle_request , cli , gevent . sleep )
def handle_request ( s , sleep ):
try :
s . recv ( 1024 )
sleep ( 0.1 )
s . send ( '''http/1.0 200 OK
Hello World! ''' )
s . shutdown ( socket . SHUT_WR )
print '.' ,
except Exception , ex :
print ex
finally :
sys . stdout . flush ()
s . close ()
if __name__ == '__main__' :
server ( 4444 )
批注:研究中。
gevent协程池服务器(无实用价值)
(webserver_gevent_pool.py) download
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
32
33
34
35
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
import gevent
from gevent import socket , sleep
from gevent.pool import Pool
def server ( port , N ):
pool = Pool ( N )
s = socket . socket ()
s . bind (( '0.0.0.0' , port ))
s . listen ( 500 )
while True :
cli , addr = s . accept ()
pool . spawn ( handle_request , cli , gevent . sleep )
def handle_request ( s , sleep ):
try :
s . recv ( 1024 )
sleep ( 0.1 )
s . send ( '''http/1.0 200 OK
Hello World! ''' )
s . shutdown ( socket . SHUT_WR )
print '.' ,
except Exception , ex :
print ex
finally :
sys . stdout . flush ()
s . close ()
if __name__ == '__main__' :
server ( 4444 , 5 )
批注:研究中。