python核心编程学习笔记-2016-08-27-01-多线程编程
2016-08-27 19:21
417 查看
18.2 线程和进程
进程是程序的一次执行,拥有自己的地址空间、内存、数据栈及其他记录其运行轨迹的辅助数据。只能使用进程间通讯(IPC),而不能共享信息。
线程,与进程有些相似。但所有线程都运行在同一个进程中。它有开始、顺序执行和结束三部分,也可能被中断、挂起。线程之间共享同一片数据空间。线程一般是并发执行的。
18.3 python、线程和全局解释器锁
全局解时器锁(GIL),对这个概念不是很理解。但它能保证同一时刻只有一个线程在运行。
在多线程环境中,python虚拟机执行方式:
1. 设置GIL;
2. 切换到一个线程去运行;
3. 运行:
a. 指定数量的字节码的指令,或者
b. 线程主动让出控制(可以调用time.sleep(0))
4. 把线程设置成睡眠状态;
5. 解锁GIL;
6. 重复上述过程。
之后是本章的所有例子。
onethr.py
mtsleep1.py
进程是程序的一次执行,拥有自己的地址空间、内存、数据栈及其他记录其运行轨迹的辅助数据。只能使用进程间通讯(IPC),而不能共享信息。
线程,与进程有些相似。但所有线程都运行在同一个进程中。它有开始、顺序执行和结束三部分,也可能被中断、挂起。线程之间共享同一片数据空间。线程一般是并发执行的。
18.3 python、线程和全局解释器锁
全局解时器锁(GIL),对这个概念不是很理解。但它能保证同一时刻只有一个线程在运行。
在多线程环境中,python虚拟机执行方式:
1. 设置GIL;
2. 切换到一个线程去运行;
3. 运行:
a. 指定数量的字节码的指令,或者
b. 线程主动让出控制(可以调用time.sleep(0))
4. 把线程设置成睡眠状态;
5. 解锁GIL;
6. 重复上述过程。
之后是本章的所有例子。
onethr.py
#-*-coding: utf-8-*- # 程序执行顺序是loop0-->loop1,在print "loop 0 done at:", ctime()执行完后,才开始执行loop1()。 from time import sleep, ctime def loop0(): print "start loop 0 at:", ctime() sleep(4) print "loop 0 done at:", ctime() def loop1(): print "start loop 1 at:", ctime() sleep(2) print "loop 1 done at:", ctime() def main(): print "starting at:", ctime() loop0() loop1() print "all DONE at:", ctime() if __name__ == "__main__": main()
mtsleep1.py
#-*-coding: utf-8-*- # 显然loop0和loop1同时运行,loop1先结束,然后loop0结束,之后再执行接下来的语句。 # sleep(6)正是让主线程休眠6s,而在这6s内,两个子线程分别将loop0()和loop1()运行完。 import thread from time import sleep, ctime def loop0(): print "start loop 0 at:", ctime() sleep(4) print "loop 0 done at:", ctime() def loop1(): print "start loop 1 at:", ctime() sleep(2) print "loop 1 done at:", ctime() def main(): print "starting at:", ctime() thread.start_new_thread(loop0,()) # 创建一个线程,并在其中运行函数loop0 thread.start_new_thread(loop1,()) # 创建另一个线程,并在其中运行函数loop1 sleep(6) # 不可缺少,由于主线程并没有停下来,它不会等两个子线程运行完后,再继续运行之后的代码。如果将这一句注释掉,程序只会运行main(),不执行loop0和loop1两个函数 print "all DONE at:", ctime() if __name__ == "__main__": main()mtsleep2.py
#-*-coding: utf-8-*- import thread from time import sleep, ctime loops = [4, 2] # 每个loop的sleep时间 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()mtsleep3.py
#-*-coding: utf-8-*- import threading from time import sleep, ctime loops = [4, 2] # 每个loop的sleep时间 def loop(nloop, nsec): print "start loop", nloop, "at:", ctime() sleep(nsec) print "loop", nloop, "done at:", ctime() def main(): print "starting at:", ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=loop, args=(i, loops[i])) # Thread对象,也是传入一个函数对象和相应的参数作为参数,但在这一步,线程并未开始。 threads.append(t) for i in nloops: threads[i].start() # 线程开始 for i in nloops: threads[i].join() # join()函数允许主线程等待子线程运行完毕,无需再管理锁 print "all DONE at:", ctime() if __name__ == "__main__": main()mtsleep4.py
#-*-coding: utf-8-*- import threading from time import sleep, ctime loops = [4, 2] class ThreadFunc(object): def __init__(self, func, args, name=''): self.name = name self.func = func self.args = args def __call__(self): apply(self.func, self.args) def loop(nloop, nsec): print "start loop", nloop, "at:", ctime() sleep(nsec) print "loop", nloop, "done at:", ctime() def main(): print "starting at:", ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=ThreadFunc(loop, (i, loops[i]), loop.__name__)) # Thread对象传入可调用的类对象作为参数,实际是可调用实例作为参数? threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print "all DONE at:", ctime() if __name__ == "__main__": main()mtsleep5.py
#-*-coding: utf-8-*- import threading from time import sleep, ctime loops = (4, 2) class MyThread(threading.Thread): def __init__(self, func, args, name=''): threading.Thread.__init__(self) # 先调用基类threading.Thread的构造器 self.name = name self.func = func self.args = args def run(self): # 定义线程的功能,在派生子类中被重写,在本例中就是运行loop()函数。 apply(self.func, self.args) def loop(nloop, nsec): print "start loop", nloop, "at:", ctime() sleep(nsec) print "loop", nloop, "done at:", ctime() def main(): print "starting at:", ctime() threads = [] nloops = range(len(loops)) for i in nloops: 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 "all DONE at:", ctime() if __name__ == "__main__": main()myThread.py
#-*-coding: utf-8-*- import threading from time import sleep, ctime loops = (4, 2) class MyThread(threading.Thread): def __init__(self, func, args, name=''): threading.Thread.__init__(self) # 先调用基类threading.Thread的构造器 self.name = name self.func = func self.args = args def getResult(self): return self.res def run(self): # 定义线程的功能,在派生子类中被重写,在本例中就是运行loop()函数。 print "starting", self.name, "at:", ctime() self.res = self.func(*self.args) print self.name, "finished at:", ctime()mtfacfib.py
#-*-coding: utf-8-*- # 先单线程运行fib, fac, sum,再多线程同时运行这三个函数 from myThread import MyThread from time import ctime, sleep def fib(x): sleep(0.005) if x < 2: return 1 return (fib(x-2) + fib(x-1)) def fac(x): sleep(0.1) if x < 2: return 1 return (x * fac(x-1)) def sum(x): sleep(0.1) if x < 2: return 1 return (x + sum(x-1)) funcs = [fib, fac, sum] n = 12 def main(): nfuncs = range(len(funcs)) print "*** SINGLE THREAD" for i in nfuncs: print "starting", funcs[i].__name__, 'at:', ctime() print funcs[i](n) print funcs[i].__name__, "finished at:", ctime() pri 4000 nt "\n*** MULTIPLE THREADS" threads = [] for i in nfuncs: t = MyThread(funcs[i], (n,), funcs[i].__name__) threads.append(t) for i in nfuncs: threads[i].start() for i in nfuncs: threads[i].join() print threads[i].getResult() print "all DONE" if __name__ == "__main__": main()prodcons.py
#-*-coding: utf-8-*- # 创建一个队列,让生产者(线程)把新生产的货物放进去供消费者(线程)使用。 from random import randint from time import sleep from Queue import Queue from myThread import MyThread def writeQ(queue): # 把对象放入队列 print "producing object for Q..." queue.put('xxx', 1) print "size now %d" % queue.qsize() def readQ(queue): # 消耗队列中的一个对象 val = queue.get(1) print "consumed object from Q... size now %d" % queue.qsize() def writer(queue, loops): # 把对象放入一个队列,等待随机秒,重复loops次 for i in range(loops): writeQ(queue) sleep(randint(1, 3)) # writer睡眠时间要短 def reader(queue, loops): # 从队列中消耗一个对象,等待随机秒,重复loops次 for i in range(loops): readQ(queue) sleep(randint(2, 5)) # reader睡眠时间要长,尽量保证reader不从空队列中消耗对象 funcs = [writer, reader] # 设置线程数 nfuncs = range(len(funcs)) def main(): nloops = randint(2, 5) q = Queue(32) threads = [] for i in nfuncs: t = MyThread(funcs[i], (q, nloops), funcs[i].__name__) threads.append(t) for i in nfuncs: threads[i].start() for i in nfuncs: threads[i].join() print "all DONE" if __name__ == "__main__": main()
相关文章推荐
- python核心编程学习笔记-2016-09-17-01-数据库编程(一)
- python核心编程学习笔记-2016-07-19-01-sys.exit()
- python核心编程学习笔记-2016-08-13-01-类属性和实例属性
- python核心编程学习笔记-2016-09-15-01-urlopen返回的对象无seek()方法
- python核心编程学习笔记-2016-09-11-01-Web编程(四)
- Python核心编程学习笔记-2016-07-24-01-理解copy和deepcopy
- python核心编程学习笔记-2016-08-21-01-客户端/服务器架构、套接字
- python核心编程学习笔记-2016-07-28-01-习题6-16
- python核心编程学习笔记-2016-07-23-01-习题5-6
- python核心编程学习笔记-2016-08-06-01-装饰器
- python核心编程学习笔记-2016-09-10-01-Web编程(一)
- python核心编程学习笔记-2016-09-16-01-cgi.FieldStorage()是经典类
- 15-多线程编程(01-AsyncTask异步任务介绍一)
- python核心编程学习笔记-2016-07-1 4000 8-01-print
- python核心编程学习笔记-2016-08-20-01-正则表达式
- python核心编程学习笔记-2016-09-03-01-图形化用户界面编程(二)
- python核心编程学习笔记-2016-08-23-01-习题16-13
- python核心编程学习笔记-2016-10-01-01-客户端COM编程
- python核心编程学习笔记-2016-08-17-01-代码对象、可执行对象声明和内建函数
- python核心编程学习笔记-2016-07-20-01-习题3-13