python学习笔记(4)-进程和线程(二)-多线程
2016-03-15 12:00
786 查看
1. 多任务可以由多进程完成,也可以由一个进程内的多个线程完成。一个进程至少有一个线程。
Python的标准库提供了两个模块,thread和threading,thread是低级模块,threading是高级模块,对thread进行了封装,绝大多数下,我们只需要使用threading这个高级模块。
启动一个线程就是把一个函数传入并创建Treading实例,然后调用start() 开始执行。
运行结果:
由于任何进程默认都会启动一个线程,我们把该线程称为主线程,主线程又可以启动新线程,Python 的threading模块有个current_threading()函数,它永远返回当前线程的实例,主线程实例的名字叫MainThread,子线程的名字在创建的时候指定,我们用LoopThread 命名子线程。
2. Lock
多线程和多进程最大的区别在于,多线程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改。
示例:
定义了一个共享变量
究其原因,是因为修改balance需要多条语句,而执行这几条语句时,线程有可能中断,从而导致i多个线程把一个对象的内容搞乱了。两个线程同时存取,导致数据不对,可以通过threading_Lock()实现加锁来控制线程修改。
示例:
当多个线程同时执行lock.acquire() 时,只有一个线程能成功的获取锁,然后继续执行代码。其他线程就等待知道获取锁为止。
锁的好处是确保了某段关键的代码只能有一个线程从头到尾的执行,坏处也当然很多,首先阻止了多线程的并发执行,包含锁的代码实际上只能以单线程执行,其次,可能有多个锁,不同的线程有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也不能结束,只能靠操作系统强行终止。
Python的标准库提供了两个模块,thread和threading,thread是低级模块,threading是高级模块,对thread进行了封装,绝大多数下,我们只需要使用threading这个高级模块。
启动一个线程就是把一个函数传入并创建Treading实例,然后调用start() 开始执行。
#!/bin/bash import time ,threading def loop(): print 'thread %s is running ...' % threading.current_thread().name n = 0 while n < 5: n = n + 1 print 'thread %s >>> %s' % (threading.current_thread().name,n) time.sleep(1) print 'thread %s is end' % threading.current_thread().name print 'thread %s is running...' % threading.current_thread().name t = threading.Thread(target=loop,name='LoopThread') t.start() t.join() print 'thread %s end' % threading.current_thread().name
运行结果:
[root@master python]# python demo12.py thread MainThread is running... thread LoopThread is running ... thread LoopThread >>> 1 thread LoopThread >>> 2 thread LoopThread >>> 3 thread LoopThread >>> 4 thread LoopThread >>> 5 thread LoopThread is end thread MainThread end
由于任何进程默认都会启动一个线程,我们把该线程称为主线程,主线程又可以启动新线程,Python 的threading模块有个current_threading()函数,它永远返回当前线程的实例,主线程实例的名字叫MainThread,子线程的名字在创建的时候指定,我们用LoopThread 命名子线程。
2. Lock
多线程和多进程最大的区别在于,多线程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改。
示例:
#!/bin/bash import time,threading balance = 0 def change_it(n): global balance balance = balance + n balance = balance - n def run_thread(n): for i in range(100000): change_it(n) t1 = threading.Thread(target = run_thread,args = (5,)) t2 = threading.Thread(target = run_thread,args = (8,)) t1.start() t2.start() t1.join() t2.join() print balance
定义了一个共享变量
balance,初始值为
0,并且启动两个线程,先存后取,理论上结果应该为
0,但是,由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,
balance的结果就不一定是
0了。
究其原因,是因为修改balance需要多条语句,而执行这几条语句时,线程有可能中断,从而导致i多个线程把一个对象的内容搞乱了。两个线程同时存取,导致数据不对,可以通过threading_Lock()实现加锁来控制线程修改。
示例:
#!/bin/bash import time, threading balance = 0 lock = threading.Lock() def change_it(n): global balance balance = balance + n balance = balance - n def run_thread(n): for i in range(100000): lock.acquire() try: change_it(n) finally: lock.release() t1 = threading.Thread(target = run_thread,args = (5,)) t2 = threading.Thread(target = run_thread,args = (8,)) t1.start() t2.start() t1.join() t2.join() print balance
当多个线程同时执行lock.acquire() 时,只有一个线程能成功的获取锁,然后继续执行代码。其他线程就等待知道获取锁为止。
锁的好处是确保了某段关键的代码只能有一个线程从头到尾的执行,坏处也当然很多,首先阻止了多线程的并发执行,包含锁的代码实际上只能以单线程执行,其次,可能有多个锁,不同的线程有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也不能结束,只能靠操作系统强行终止。
相关文章推荐
- Python3使用requests包抓取并保存网页源码的方法
- Python减少循环层次和缩进的技巧分析
- Python作用域用法实例详解
- python 之select
- python内建方法
- Python的净值数据接口调用示例分享
- python 反射调用
- Python函数中的函数(闭包)用法实例
- python实现各个排序算法【转】
- python学习-异常处理
- eclipse python插件地址选择以及安装
- JPype:实现在python中调用JAVA
- python微信机器人之aliyun服务器
- python(5) 获取acfun弹幕,评论和视频信息
- python 装饰器
- 使用Coverage分析Python web项目的代码覆盖率
- python微信机器人之小i
- Python程序的执行过程
- python 微信机器人之图灵
- python内存管理机制