Python多线程小例子

版权声明:拥抱开源,欢迎转载,转载请保留原文链接~ https://blog.csdn.net/u010429424/article/details/76100149

Python多线程小例子

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

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

from time import ctime
import threading

def 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()
    for t in thread_list:
        t.join()  # 在这个子线程完成运行之前,主线程将一直被阻塞

    print('thread %s ended.' % threading.current_thread().name)
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

运行效果如下:

这里写图片描述

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

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

这里写图片描述

2、lock 锁

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

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

import threading

money = 0 # 变量 money 被 t1和 t2 两个线程共享

# 存钱
def put_money(sum):
    global money
    money += sum

# 取钱
def get_money(sum):
    global money
    money -= sum

def 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)
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

在上面的例子中,我们先存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......别忘了释放锁:
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

“当多个线程同时执行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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值