今天,看了python 核心编程的第四章,多线程编程,记录一下要点。
1、进程和线程
进程是一个执行中的程序,每个进程都有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据.。
线程,实在同一个进程下执行的,共享相同的上下文,一个进程中的各个线程与主线程共享一片数据空间,线程之间的信息共享和通信会更加容易。
2、使用多线程
python 中有thread 模块和 threading 模块
thread模块的核心函数是thread.start_new_thread(),使用thread模块的事例.
import thread
from time import ctime, sleep
loops = [4,2]
def loop(nloop, nsec, lock):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:' , ctime()
lock.release()
def main():
print 'starting at:', ctime()
locks = []
nloops = range(len(loops))
for i in nloops:
lock = thread.allocate_lock()
lock.acquire()
locks.append(lock)
for i in nloops:
thread.start_new_thread(loop,(i, loops[i], locks[i]))
for i in nloops:
while locks[i].locked():
pass
print 'all Done at: ', ctime()
if __name__ == '__main__':
main()
threading 模块
threadIng模块与thread模块相比,它支持守护线程。守护线程的概念可以这样理解,如果一个线程设置为守护线程,就表示这个线程是不重要的,进程退出时不需要等待这个线程执行完成。
如果要将一个线程设置为守护线程,需要在线程执行之前,设置 thread.daemon = True
使用Thread 类创建多线程事例,
import threading
from time import sleep, ctime
class MyThread(threading.Thread):
"""docstring for MyThread"""
def __init__(self, func, args, name=''):
super(MyThread, self).__init__()
self.name = name
self.func = func
self.args = args
def getResult(self):
return self.res
def run(self):
self.res = self.func(*self.args)
loops = [4,2]
def loop(nloop, nsec):
print 'start loop', nloop, 'at: ', ctime()
sleep(nsec)
print 'loop done', nloop, 'at: ', ctime()
return 'ws'
def main():
print 'starting at: ', ctime()
threads = []
nloops = range(len(loops))
for i in nloops:
#t = threading.Thread(target = loop, args = (i, loops[i]))
t = MyThread(loop,(i,loops[i]),loop.__name__)
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print threads[i].getResult()
if __name__ == '__main__':
main()
3、同步原语
使用同步的情况,在使用多线程时,有些特定的函数或者代码块不希望被多个线程同时执行。
#!/usr/bin/env python
from atexit import register
from random import randrange
from threading import Thread, Lock, currentThread
from time import sleep, ctime
class CleanOutputSet(set):
def __str__(self):
return ', '.join(x for x in self)
lock = Lock()
loops = (randrange(2, 5) for x in xrange(randrange(3, 7)))
remaining = CleanOutputSet()
def loop(nsec):
myname = currentThread().name
lock.acquire()
remaining.add(myname)
print '[%s] Started %s' % (ctime(), myname) #print '[{0}] Started {1}'.format(ctime(), myname)
lock.release()
sleep(nsec)
lock.acquire()
remaining.remove(myname)
print '[%s] Completed %s (%d secs)' % ( #print '[{0}] Completed {1} ({2} secs)'.format(
ctime(), myname, nsec)
print ' (remaining: %s)' % (remaining or 'NONE') #print ' (remaining: {0})'.format(remaining or 'NONE')
lock.release()
def _main():
for pause in loops:
Thread(target=loop, args=(pause,)).start()
@register
def _atexit():
print 'all DONE at:', ctime()
if __name__ == '__main__':
_main()
python支持的多种类型的同步原语,包括锁/互斥、信号量
使用锁时,调用lock.require()函数获取锁,调用lock.release()函数释放锁