关于Python的线程程序设计

一、为什么用线程(Thread)?
    在现阶段应用程序设计技术中,线程扮演很重要的角色,比如好多中间件是基于线程的、JAVA GUI应用等。
    大面积应用采用线程的理由如下:
    1、并行计算
    2、并行I/O处理
    3、异步I/O事件处理
二、什么是线程(Thread)?
    1、先说一下什么是进程(Process)?
      通过学习操作系统的基本原理你可以了解到它的重要性和有用性,主要是提升CPU的处理效率,主要内容有:什么是进程,进程的状态,进程的调度,进程的结构与标识, 进程的空间,进程的上下文切换,进程的处理方法,进程与程序的区别等。
    2、线程是类似进程的,只有大小、粒度的不同

   
线程有时也叫轻量级(lightweight)进程,占有比线程更小的空间,切换的代价小,实际情况下依赖于具体的线程系统,它们都有自己的中断方法,关
于中断的技术要引起关注,因为线程的粒度小,有时要引起极大的关注,都可以创建自己的子线程或子进程,在UNIX/LINUX中用fork()创建子线
程,子共亨父的方法也是类同的。
三、Python的线程模块
    有两个thread.py和threading.py,前者是早期的,相对来说简单一些。
    用例子说明如下,注意研究lock是如何形成的
      server.py
    # this is the server
import socket  # networking module
import sys
import thread
# note the globals v and nclnt, and their supporting locks, which are
#    also global; the standard method of communication between threads is
#    via globals
# function for thread to serve a particular client, c
def serveclient(c):
      global v,nclnt,vlock,nclntlock
      while 1:
              # receive letter from c, if it is still connected
              k = c.recv(1)
              if k == ' ': break
              # concatenate v with k in an atomic manner, i.e. with protection
              #    by locks
              vlock.acquire()
              v += k
              vlock.release()
              # send new v back to client
              c.send(v)
              c.close()
              nclntlock.acquire()
              nclnt -= 1
              nclntlock.release()
# set up Internet TCP socket
lstn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = int(sys.argv[1]) # server port number
# bind lstn socket to this port
lstn.bind(('127.0.0.1', 4000))
# start listening for contacts from clients (at most 2 at a time)
lstn.listen(5)
# initialize concatenated string, v
v = ' '
# set up a lock to guard v
vlock = thread.allocate_lock()
# nclnt will be the number of clients still connected
nclnt = 2
# set up a lock to guard nclnt
nclntlock = thread.allocate_lock()
# accept calls from the clients
for i in range(nclnt):
      # wait for call, then get a new socket to use for this client,
      #    and get the client's address/port tuple (though not used)
      (clnt,ap) = lstn.accept()
      # start thread for this client, with serveclient() as the thread's
      #    function, with parameter clnt; note that parameter set must be
      #    a tuple; in this case, the tuple is of length 1, so a comma is
      #    needed
      thread.start_new_thread(serveclient(clnt))
# shut down the server socket, since it's not needed anymore
lstn.close()
# wait for both threads to finish
while nclnt > 0: pass
print 'the final value of v is', v
  client1.py
# simple illustration of thread module
# two clients connect to server; each client repeatedly sends a letter,
# stored in the variable k, which the server appends to a global string
#
v, and reports v to the client; k = ' 'means the client is dropping
out; when all clients are gone, server prints the final string v
# this is the client; usage is
#    python clnt.py server_address port_number
import socket  # networking module
import sys
# create Internet TCP socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1] # server address
port = int(sys.argv[2]) # server port
# connect to server
s.connect((host,port ))
while(1):
# get letter
        k = raw_input('enter a letter:')
        s.send(k) # send k to server
# if stop signal, then leave loop
        if k == ' ': break
v= s.recv(1024)  # receive v from server (up to 1024 bytes)
print  v
s.close() # close socket
下面是threading的,联系java想一下相关方面 srvr如何?
# simple illustration of threading module
# multiple clients connect to server; each client repeatedly sends a
# value k, which the server adds to a global string v and echos back
# to the client; k = ’’ means the client is dropping out; when all
# clients are gone, server prints final value of v
# this is the server
import socket # networking module
import sys
import threading
# class for threads, subclassed from threading.Thread class
class srvr(threading.Thread):
        # v and vlock are now class variables
        v = ’’
        vlock = threading.Lock()
        id = 0 # I want to give an ID number to each thread, starting at 0
        def __init__(self,clntsock):
              # invoke constructor of parent class
              threading.Thread.__init__(self)
              # add instance variables
              self.myid = srvr.id
              srvr.id += 1
              self.myclntsock = clntsock
      # this function is what the thread actually runs; the required name
      #    is run(); threading.Thread.start() calls threading.Thread.run(),
      #    which is always overridden, as we are doing here
      def run(self):
              while 1:
                    # receive letter from client, if it is still connected
                    k = self.myclntsock.recv(1)
                    if k == ’’: break
                    # update v in an atomic manner
                    srvr.vlock.acquire()
                    srvr.v += k
                    srvr.vlock.release()
                    # send new v back to client
                    self.myclntsock.send(srvr.v)
            self.myclntsock.close()
# set up Internet TCP socket
lstn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = int(sys.argv[1]) # server port number
# bind lstn socket to this port
lstn.bind((’’, port))
# start listening for contacts from clients (at most 2 at a time)
lstn.listen(5)
nclnt = int(sys.argv[2])  # number of clients
mythreads = [] # list of all the threads
# accept calls from the clients
for i in range(nclnt):
      # wait for call, then get a new socket to use for this client,
      #    and get the client’s address/port tuple (though not used)
        (clnt,ap) = lstn.accept()
      # make a new instance of the class srvr
      s = srvr(clnt)
      # keep a list all threads
      mythreads.append(s)
      # threading.Thread.start calls threading.Thread.run(), which we
      #    overrode in our definition of the class srvr
      s.start()
# shut down the server socket, since it’s not needed anymore
lstn.close()
# wait for all threads to finish
for s in mythreads:
      s.join()
print ’the final value of v is’, srvr.v