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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值