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

来源:互联网 发布:win7一拖二软件 编辑:程序博客网 时间:2024/03/28 23:18


1. 多任务可以由多进程完成,也可以由一个进程内的多个线程完成。一个进程至少有一个线程。

Python的标准库提供了两个模块,thread和threading,thread是低级模块,threading是高级模块,对thread进行了封装,绝大多数下,我们只需要使用threading这个高级模块。
启动一个线程就是把一个函数传入并创建Treading实例,然后调用start() 开始执行。


#!/bin/bashimport time ,threadingdef 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().nameprint 'thread %s is running...' % threading.current_thread().namet = threading.Thread(target=loop,name='LoopThread')t.start()t.join()print 'thread %s end' % threading.current_thread().name

运行结果:

[root@master python]# python demo12.pythread MainThread is running...thread LoopThread is running ...thread LoopThread >>> 1thread LoopThread >>> 2thread LoopThread >>> 3thread LoopThread >>> 4thread LoopThread >>> 5thread LoopThread is endthread MainThread end

由于任何进程默认都会启动一个线程,我们把该线程称为主线程,主线程又可以启动新线程,Python   的threading模块有个current_threading()函数,它永远返回当前线程的实例,主线程实例的名字叫MainThread,子线程的名字在创建的时候指定,我们用LoopThread 命名子线程。
2. Lock
多线程和多进程最大的区别在于,多线程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改。
示例:

#!/bin/bashimport time,threadingbalance  = 0def change_it(n):        global balance        balance = balance + n        balance = balance - ndef 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/bashimport time, threadingbalance = 0lock = threading.Lock()def change_it(n):        global balance        balance = balance + n        balance = balance - ndef 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() 时,只有一个线程能成功的获取锁,然后继续执行代码。其他线程就等待知道获取锁为止。
锁的好处是确保了某段关键的代码只能有一个线程从头到尾的执行,坏处也当然很多,首先阻止了多线程的并发执行,包含锁的代码实际上只能以单线程执行,其次,可能有多个锁,不同的线程有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也不能结束,只能靠操作系统强行终止。

0 0
原创粉丝点击