Python学习并发之threading库

1.简介:

  • Python 很早就开始使用多种不同的并发编程方法,包括多线程加载子进程等。

2.单线程引入:

  • 先看一段代码:
    #coding=utf-8
    import time
    
    def greet(index):
        print '人生苦短,我用Python!-%d' % index
        time.sleep(0.5)
        
    def line_run():
        for i in range(5):
            greet(i)
    
    if __name__ == "__main__":#入口函数的判断
        line_run()
    
    #结果:当然是依次顺序的打印这句话了,,,
    人生苦短,我用Python!-0
    人生苦短,我用Python!-1
    人生苦短,我用Python!-2
    人生苦短,我用Python!-3
    人生苦短,我用Python!-4
    
    Process finished with exit code 0
    
注意:
  • if __name__ == "__main__":----------------简要说明如下:
    • 有句话经典的概括了这段代码的意义:Make a script both importable and executable
    • 意思就是让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行。
    • 调试代码的时候,在if __name__ == '__main__'中加入一些我们需要调试的代码,可以让外部模块调用的时候不执行调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!

3.多线程引入:

  • 改进后的代码:
    #coding=utf-8
    import time
    import threading
    def greet(index):
        print '人生苦短,我用Python!-%d'%index
        time.sleep(0.5)
    
    def async_run():
        for i in range(5):
            th = threading.Thread(target=greet,args=[i])#target指的函数名args为参数
            th.start()
    
    if __name__ == "__main__":
        async_run()
    #结果:同时打印下列的语句:请自己亲测方能看到效果。
    人生苦短,我用Python!-0
    人生苦短,我用Python!-1
    人生苦短,我用Python!-2
    人生苦短,我用Python!-3
    人生苦短,我用Python!-4
    

4.threading库可用来在单独的线程中执行任意的Python可调用对象。

  • t = threading.Thread(target=函数名,args=[参数])#创建线程t。
  • t.start()执行线程。
  • 当创建一个线程实例时,在调用它的start()方法之前(需要提供目标函数以及相应的参数),线程并不会立即执行。
  • 该线程实例完全由操作系统来管理。一旦启用后,线程就开始独立运行,直到目标函数返回为至。
  • 可以通过查询线程实例来判断它是否还在运行。t.is_alive()---查看线程是否运行
  • t.join()请求连接到某个线程上,这个方法会等待线程结束。
  • 对于需要长时间运行的线程或者一直不断运行的后台任务,应该考虑将这些线程设置为daemon(即,守护线程):t = threading.Thread(target=函数名,args=[参数],daemon=True)
    注意:daemon线程是无法被连接的。但是当主线程结束后则会自动销毁。

5.举例:生产者和消费者

  • 代码:两个线程对公共变量MONEY操作
    #coding=utf-8
    import time
    import threading
    import random
    MONEY = 0#全局变量MONEY
    gLock = threading.Lock()#锁
    #生产者
    def procuder():
        while True:
            global MONEY#声明一个全局变量
            rand_money = random.randint(10,100)#随机生产一个数值
            gLock.acquire()#用acquire()申请锁
            MONEY += rand_money
            gLock.release()#释放锁
            print '生产者%s-生产了:%d' % (threading.current_thread, MONEY)
            time.sleep(0.5)#睡眠
    
    #消费者
    def customer():
        while True:
            global MONEY #声明一个全局变量
            rand_money = random.randint(10,100)#随机生成一个数值
            if MONEY > rand_money:
                print '消费者%s-消费了:%d' %(threading.current_thread,rand_money)
                gLock.acquire#加锁
                MONEY -= rand_money
                gLock.release#释放
            else:
                print '需要消费的钱为:%d,余额为:%d' %(rand_money,MONEY)
    
  • threading.Lock()创建锁,用acquire()申请锁,每次只有一个线程获得锁,其他线程必须等此线程release()后才能获得锁。
  • RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。
    注意:如果使用RLock,那么acquirerelease必须成对出现,即同一线程中调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。

你可能感兴趣的:(Python学习并发之threading库)