Python中多进程与多线程实例(二)编程方法

零下一度
发布: 2017-06-01 10:01:10
原创
1704 人浏览过

  在上一章中,学习了Python多进程编程的一些基本方法:使用跨平台多进程模块multiprocessing提供的Process、Pool、Queue、Lock、Pipe等类,实现子进程创建、进程池(批量创建子进程并管理子进程数量上限)以及进程间通信。这一章学习下Python下的多线程编程方法。

一、threading

线程是操作系统执行任务的最小单元。Python标准库中提供了threading模块,对多线程编程提供了很便捷的支持。

下面是使用threading实现多线程的代码:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7  8 import threading, time 9 10 def test(index):11     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))12     print 'thread %s starts.' % threading.current_thread().name13     print 'the index is %d' % index14     time.sleep(3)15     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))16     print 'thread %s ends.' % threading.current_thread().name17 18 if name == "main":19     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))20     print 'thread %s starts.' % threading.current_thread().name21     #创建线程22     my_thread = threading.Thread(target = test, args=(1,) , name= 'zni_feng_thread')23     #等待2s24     time.sleep(2)25     #启动线程26     my_thread.start()27     #等待线程结束28     my_thread.join()29     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))30     print 'thread %s ends.' % threading.current_thread().name
登录后复制

输出结果为:

2017-01-12 22:06:32
thread MainThread starts.
2017-01-12 22:06:34
thread zni_feng_thread starts.
the index is 1
2017-01-12 22:06:37
thread zni_feng_thread ends.
2017-01-12 22:06:37
thread MainThread ends.
[Finished in 5.1s]
登录后复制

其中,threading模块的current_thread()函数会返回当前线程的实例。

二、Lock

多进程与多线程的最大不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响。而多线程中,所有变量都由所有线程共享,所以,任何一个共享变量都可以被任何一个线程修改。因此线程之间共享数据最大的危险在于多个线程同时改变一个变量。为了解决这个问题,我们可以借助于threading模块的Lock类给共享变量加锁。

先看看使用多线程写同一个共享变量,不加锁的例子:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7 import threading 8  9 class Account:10     def init(self):11         self.balance = 012 13     def add(self):14         for i in range(0,100000):15             self.balance += 116 17     def delete(self):18         for i in range(0,100000):19             self.balance -=1 
20 21 if name == "main":22     account  = Account()23     #创建线程24     thread_add = threading.Thread(target=account.add, name= 'Add')25     thread_delete = threading.Thread(target=account.delete, name= 'Delete')26 27     #启动线程28     thread_add.start()29     thread_delete.start()30     31     #等待线程结束32     thread_add.join()33     thread_delete.join()34 35     print 'The final balance is: ' + str(account.balance)
登录后复制

运行结果为:

The final balance is: -51713
[Finished in 0.1s]
登录后复制

可以发现,每次运行,它的最终结果都会不同,而且都不是0。就是因为不同线程在同时修改同一个变量时,发生了冲突,某些中间变量没有按顺序被使用导致。

现在我们使用Lock对程序进行加锁:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7 import threading 8  9 class Account:10     def init(self):11         self.balance = 012 13     def add(self, lock):14         #获得锁15         lock.acquire()16         for i in range(0,100000):17             self.balance += 118         #释放锁19         lock.release()20 21     def delete(self, lock):22         #获得锁23         lock.acquire()24         for i in range(0,100000):25             self.balance -=1 
26         #释放锁27         lock.release()28 29 30 if name == "main":31     account  = Account()32     lock = threading.Lock()33     #创建线程34     thread_add = threading.Thread(target=account.add, args=(lock, ), name= 'Add')35     thread_delete = threading.Thread(target=account.delete, args=(lock, ), name= 'Delete')36 37     #启动线程38     thread_add.start()39     thread_delete.start()40     41     #等待线程结束42     thread_add.join()43     thread_delete.join()44 45     print 'The final balance is: ' + str(account.balance)
登录后复制

可以发现,无论如何执行多少次,balance结果都为0。如果将每次balance计算的结果都打印出来,还会发现,当一个线程开始执行时,另一个线程一定会等到前一个线程执行完(准确地说是lock.release()执行完)后才开始执行。

The final balance is: 0
[Finished in 0.1s]
登录后复制

【相关推荐】

1. Python中多进程与多线程实例(一)

2. Python中推荐使用多进程而不是多线程?分享推荐使用多进程的原因

3. python多进程快还是多线程快?

4. 关于Python进程、线程、协程详细介绍

5. Python 并发编程之线程池/进程池

以上是Python中多进程与多线程实例(二)编程方法的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!