您的位置:首页 > 编程语言 > Python开发

python学习笔记(4)-进程和线程(二)-多线程

2016-03-15 12:00 786 查看
1. 多任务可以由多进程完成,也可以由一个进程内的多个线程完成。一个进程至少有一个线程。

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() 时,只有一个线程能成功的获取锁,然后继续执行代码。其他线程就等待知道获取锁为止。
锁的好处是确保了某段关键的代码只能有一个线程从头到尾的执行,坏处也当然很多,首先阻止了多线程的并发执行,包含锁的代码实际上只能以单线程执行,其次,可能有多个锁,不同的线程有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也不能结束,只能靠操作系统强行终止。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: