首页 > 代码库 > 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用来读取队列中的信息。运行结果如下:
值得一提的是打印并不是一瞬间完成的,而是慢慢一行一行的完成的。
另外我思考了一下,如果消息需要定向的投入到某个线程中怎么办,在reader很多的情况下这样的消息队列并不能确定谁会得到这个消息,初步想了下,将消息结构化让它有一个属性来表示接受方就行了。
本文出自 “aL的自学记录” 博客,请务必保留此出处http://al0707.blog.51cto.com/9215022/1537358