一、为什么用线程(
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