Python's Archiver

為方便港臺同胞閱覽,Python中國特別推出簡繁體內容轉換功能

xieaotian 发表于 2008-11-17 11:29

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]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.