首页 > 代码库 > 14-08-07 关于程序、进程、线程,以及python中实现多线程的办法

14-08-07 关于程序、进程、线程,以及python中实现多线程的办法

    考核题目中涉及到多线程编程,于是复习了一下系统编程里面的各种概念。

    首先,程序是代码,没有活动。通过编译连接之后被加载到内存里运行时,内存活动的就是进程,这里的进程不仅仅是代码段,还包括涉及的数据等。而线程是在同一个进程下的小程序,它们可以“同时”地运行,其中会有一个主线程来控制。

    接下来是多线程或着多进程的实现,两者原理基本一样,都是把CPU的时间分片然后进行分配给某个进程或者线程,也就是说在同一个时间只会有一个线程在使用CPU,但是CPU切换线程的频率非常快使得它们看上去是在同一个事件运行的。

    

    python中实现多线程编程主要依靠两个模版,一是threading(或者thread)和Queue,前者用来创建和管理线程,后者则用来实现线程之间的消息传递。


    关于threading,其中包含一个Thread类,构造时只需要提供这个线程运行的函数(target)和函数相应的参数(args)即可, 其中参数是一个元组。Thread类完成定义后使用.start()函数开始执行线程。

    利用Thread类创建线程的时候有三种方式:

        创建一个Tread类的实例并且传给它一个函数。

        创建一个Tread类的实例并且传给它一个可调用的类对象。

        派生出一个Tread类的子类,再创建这个子类的实例。

    我们知道,当主线程退出时,不管其他线程是否运行完,都会被关闭。但往往我们不想让这样的事情发生,这时就需要在主函数里面调用.join()函数来进行控制,这个函数的作用是判断一个线程(Tread类)是否运行结束,结束的话继续运行代码,未结束将运行这个函数的线程挂起(sleep)。如果有多个副线程,则可以使用循环去判断每一个Tread是否结束。


    关于Queue模版,提供一个供多进程使用的同步先进先出(不同于堆栈)队列,其中主要是一个Queue对象,可以把它当作一个消息队列,创建时有一个size参数来确定其大小,Queue对象函数主要有:qsize()返回队列的实时大小;empty()和full()判断队列为空或者已满;put(item,block=0)用于将item加入列表,block不为0时函数会暂停线程直到

有空间放置对象;get(block=0)用于从队列中读取一个信息,block作用同put()函数。


下面是写的一个代码和结果:


from time import ctime
from time import sleep
from Queue import Queue
from threading import Thread
from random import randint


def writeQ(queue):
	print ‘producting obj for Q...‘,
	queue.put(‘xxx‘,1)
	print ‘size now‘,queue.qsize()
	
def readQ(queue):
	val=queue.get(1)
	print ‘consumed item from Q... size now‘,queue.qsize()
	
def writer(queue,n):
	print ‘--writer start at :‘,ctime()
	for i in range(n):
		writeQ(queue)
		sleep(randint(1,3))
	print ‘--writer end at :‘,ctime()
	
def reader(queue,n):
	print ‘--reader start at :‘,ctime()
	for i in range(n):
		readQ(queue)
		sleep(randint(2,5))
	print ‘--reader end at :‘,ctime()
	
	
funcs=[writer,reader]
nfuncs=range(len(funcs))
threads=[]
n=randint(4,7)
q=Queue(32)


for i in nfuncs:
	t=Thread(target=funcs[i],args=(q,n))
	threads.append(t)
print ‘All start at :‘,ctime()
for i in nfuncs:
	threads[i].start()
for i in nfuncs:
	threads[i].join()
print ‘All done at :‘,ctime()

     其中q是一个消息队列,writer用来向队列中写入信息,reader用来读取队列中的信息。运行结果如下:

     wKiom1PkTfbAmuMhAALpn_igpHs784.jpg

    值得一提的是打印并不是一瞬间完成的,而是慢慢一行一行的完成的。

    另外我思考了一下,如果消息需要定向的投入到某个线程中怎么办,在reader很多的情况下这样的消息队列并不能确定谁会得到这个消息,初步想了下,将消息结构化让它有一个属性来表示接受方就行了。

本文出自 “aL的自学记录” 博客,请务必保留此出处http://al0707.blog.51cto.com/9215022/1537358