Python 线程 初探 (1)
线程管理在进行网络编成时经常用到,为了网络操作能和界面异步或服务器同时为多个用户提供服务等。对于多线程的问题, Python有两种方式能够实现,一种是Unix平台下的著名的fork(),fork出来的是一个新的进程,而在Python内部,像大多数现代编程语言,存在线程管理。每个线程要比进程占用的资源少,线程不在内存中产生自己的代码片断,而只是保存同一段代码的不同状态(我道听途说的).
以下sample实现了一个简单的网络应用:多个用户端捕捉用户输入的字符发送给服务器, 服务器根据接收到的顺序,将他们拼接到一起,最终显示出来。
这个sample的服务器段使用了Python多线程。(Python Thread)
客户端 clnt.py
#!/usr/bin/env python
import socket;
import sys;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1] #Server Address
port = int(sys.argv[2]) #Server Port
s.connect((host,port))
while(1):
#get a letter
k = raw_input('Input a letter')
s.send(k)
if k == '':
break
v = s.recv(1024) #receive from server.
print v
s.close()
服务器段: srvr.py
#!/usr/bin/env python
import socket
import sys
import thread
#funcation for thread to serve a particular client
def serverclient(c):
global v, nclnt, vlock, nclntlock
while 1:
#receive letters from client.
k = c.recv(1)
if k == "":
break
#update v as an atomic task.
vlock.acquire()
v += k
vlock.release()
c.send(v)
c.close()
nclntlock.acquire()
nclnt -= 1
nclntlock.release()
print 'one client has just shutted'
#set up Internet TCP socket
lstn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = int(sys.argv[1])
lstn.bind(('',port))
#start listen
lstn.listen(5)
v = ''
vlock = thread.allocate_lock()
nclnt = 2
nclntlock = thread.allocate_lock()
for i in range(nclnt):
#wait for call , then get a new socket to use for this client.
#get the client's (address,port) tuple.
print 'Waiting for clinet to join in'
(clnt, ap) = lstn.accept()
print 'new client detected:'
print (clnt, ap)
#start new thread for this client
thread.start_new_thread(serverclient,(clnt,))
#shut down server socket.
lstn.close()
while nclnt > 0:
pass
print 'the final value of v is', v
while 1:
w = raw_input()
if (w == ''):
break
pass
--------------------------code ends here------------------------
要理解以上代码中的python thread , 你首先要对一般的sokcet 有所了解,client主动connect 服务器:
s.connect((host,port))
host是主机名,port端口,(host,port)是python内建的数据结构"tuple",不要理解为括号打多了...
lstn.bind(('',port))
是服务器邦定监听的端口,这个操作和之前的connect都可能被防火墙侦测到。
lstn.accpet()将阻塞线程,直到有外来网络连接连接到邦定的监听端口上。
另外,其他一些多线程程序常用的知识:进程同步与并发控制 等等.
vlock, 字符串v的并发控制锁
nclntlock, number of client lock. 客户端数量的并发控制锁。
注意Sample Code里:除了初始化操作,凡是对v和nclnt操作之前都通过这两个变量进行并发控制。
最关键的方法:
thread.start_new_thread(serverclient,(clnt,))
作用非常显然,它启动了一个新的线程来执行先前我们定义的serverclient方法,并将(clnt,)作为参数传递给serverclient.
页:
[1]