Python多线程小例子

来源:互联网 发布:饥荒联机mod知乎 编辑:程序博客网 时间:2024/05/16 17:12

Python多线程小例子

1、在主线程中创建子线程

下面的代码一共创建了三个线程:主线程、coding 线程和music 线程,最后使用thread_list 装载线程

from time import ctimeimport threadingdef coding(language):    for i in range(5):        print('I\'m coding ',language, ' program at ', ctime() )def music():    for i in range(5):        print('I\'m listening music at ', ctime())if __name__ == '__main__':    print('thread %s is running...' % threading.current_thread().name)    thread_list = []    t1 = threading.Thread(target=coding, args=('Python',))    t2 = threading.Thread(target=music)    thread_list.append(t1)    thread_list.append(t2)    for t in thread_list:        t.setDaemon(True)  # 设置为守护线程        t.start()        t.join()  # 在这个子线程完成运行之前,主线程将一直被阻塞    print('thread %s ended.' % threading.current_thread().name)

运行效果如下:

这里写图片描述

t.join()的作用是:在子线程完成运行前,主线程将处于阻塞的状态,否则主线程会一直运行,并且主线程运行结束后,子线程也一同结束。

如果我们把join去掉,则运行结果可能为:

这里写图片描述

2、lock 锁

在多线程中,变量由各个线程共享,对共享变量,需要加锁。

举一个最常见的例子:我们经常在银行存钱、取款,其中一个线程负责存钱,另一个线程负责取款。如果不加控制,很容易就把钱数算错了。我们看看银行是怎么算错钱数的:

import threadingmoney = 0 # 变量 money 被 t1和 t2 两个线程共享# 存钱def put_money(sum):    global money    money += sum# 取钱def get_money(sum):    global money    money -= sumdef run_thread(sum):    for i in range(1000000): #执行的次数要足够多        # 先存sum,后取sum,钱数应当为0        put_money(sum)         get_money(sum)t1 = threading.Thread(target=run_thread, args=(100,))t2 = threading.Thread(target=run_thread, args=(1000,))t1.start()t2.start()t1.join()t2.join()print(money)

在上面的例子中,我们先存sum元钱,再取sum元钱,总钱数应当一直为0。这在单线程中没有问题。

然而在多线程中,操作系统交叉执行赋值语句,导致全局变量被一个线程修改了,另一个线程却不知情的情况。

因为在操作系统中,money += sum,是被拆成两条语句执行的:
  x = money + sum
  money = x

这两条语句的执行顺序 很可能是乱序的,我们看看下面的表格就理解了,最后你会惊奇地发现 少了5元钱!:-(

这里写图片描述

实际结果也验证了这一问题:

这里写图片描述

哈哈哈,我们居然多出了2900元。很显然,银行家们肯定不能允许这种情况发生,所以,他们也在学习如何使用lock :-)

可以通过lock解决这个问题:

def run_thread(sum):    for i in range(1000000):        lock.acquire() # 改动1...........加锁        try:            put_money(sum)            get_money(sum)        finally:            lock.release()  # 改动2......别忘了释放锁:

“当多个线程同时执行lock.acquire()时,只有一个线程能成功地获取锁,然后继续执行代码,其他线程就继续等待直到获得锁为止。”————引用自多线程-廖雪峰的官方网站

其实和上厕所一个道理,一个人蹲坑,另一个人只能等着 :-)

这下好了,银行家们在 run_thread 方法中添加了lock,这次程序运行的结果如下,我们看到钱数始终为0:

这里写图片描述

除了多线程外,Python 多进程也经常使用,参见:
http://blog.csdn.net/u010429424/article/details/76147368

参考:
http://www.cnblogs.com/fnng/p/3670789.html
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192823818768cd506abbc94eb5916192364506fa5d000

See u ~

这里写图片描述

原创粉丝点击