美文网首页python线程相关
多线程 -- threading

多线程 -- threading

作者: 钱塘 | 来源:发表于2017-08-18 15:02 被阅读53次

多线程模块 threading

  • 创建多线程的两种方式:

    
    import threading
    import time
    
    
    
  • 创建线程的第一种方式

    def foo(n):
        pass
    print('hello world')
        
    t1 = threading.Thread(target=foo, args=(1,))
    t1.start()
    
  • 创建线程的第二种方式

``` 
class MyThread(threading.Thread):

    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num   # 对象里的字段  # self 是 t1或t2

    def run(self):

        print("running on number: %s" % self.num)

        time.sleep(3)

if __name__ == '__main__':
    t1 = MyThread(1)  # 实例化一个类的对象,执行构造方法
    t2 = MyThread(2)

    t1.start()
    t2.start()
``` 
  • 创建线程:
    import threading
    t1 = threading.Thread(target=music, args=('七里香',))
    
    target指向函数,args指向函数的参数
  • 启动线程:

      t.start()
    
  • 阻塞线程:

      t.join()    阻塞直到线程t结束   
    
  • 多线程实例1

      import threading
      from time import ctime, sleep
      import time
          
      # 预计耗时4秒
      def music(func):
          for i in range(2):
              print("I was listening to %s. %s" % (func, ctime()))
              sleep(2)
              print("end listening %s" %ctime())
      
      # 预计耗时6秒
      def movie(func):
          for i in range(2):
              print("Begin watching at the %s! %s" % (func,ctime()))
              sleep(3)
              print("end watching %s" % ctime())
      
      
      # 创建线程1,2
      
      threads = []
      t1 = threading.Thread(target=music, args=('七里香',))
      threads.append(t1)
      t2 = threading.Thread(target=movie, args=('十三区',))
      threads.append(t2)
      
      
      if __name__ == '__main__':
          for t in threads:
              t.start()
          start = time.time()
          t2.join()
          end = time.time()
      
      
          # t2.join()    # join阻塞
          print("总共耗时 %s" % (end-start))
          
          
      # 结果:总共耗时 6.004828929901123
    
  • 多线程 -- 计算密集型

    import threading
    import time
    
    begin = time.time()
    
    def add(n):
        sum = 0
        for i in range(n):
            sum += i
        print(sum)
    
    
    # 单线程串行计算
    # add(10000000)
    # add(10000000)
    
    
    # 多线程并行计算
    t1 = threading.Thread(target=add, args=(10000000,))
    t1.start()
    # print('1开始了')
    
    t2 = threading.Thread(target=add, args=(10000000,))
    t2.start()
    # print('2也开始了')
    
    t1.join()
    t2.join()
    #
    end = time.time()
    
    print(end-begin)
    
    
    # 串行花费 14.73 秒  两者都是计算密集型,都在抢CPU
    # 并行花费 15.71 秒  并行反而更多,因为切换还需要时间
    
    # IO密集型任务或函数
    # 计算密集型任务
    
    # GIL全局解释锁  如果只有一颗CPU,无法解决计算密集型的任务 只有Cpython有这个bug
    
  • 多线程 -- IO密集型

    import time
    import threading
    
    
    def foo(n):                         # 设定3秒
        print('线程1开始')
        print('foo %s' % n)
        # print('foo')
        time.sleep(3)
        print('线程1结束\n')
    
    
    def bar(n):                         # 设定1秒
        print('线程2开始')
        print('bar %s' % n)
        time.sleep(1)
        # print('ok')
        print('线程2结束')
    
    
    # t1 t2 即为线程
    # target = 要执行的函数 args = 参数
    t1 = threading.Thread(target=foo, args=(1,))
    t2 = threading.Thread(target=bar, args=(2,))
    
    print('...... in the main  ........')
    
    # 线程执行 start()
    
    begin = time.time()
    
    t1.start()  # 线程开始
    t2.start()  # 线程开始
    
    t1.join()  # 子线程不结束不往下走
    t2.join()  # 子线程不结束不往下走
    
    end = time.time()
    print('整个程序一共花了', end - begin, '秒,asshole')  #
    
    
    # 运行结果: 整个程序一共花了 3.003476858139038 秒,asshole
        
    
  • 死锁

    # 死锁怎么办?
    # 用递归锁解决死锁问题,递归锁可重用
    
    import threading, time
    
    class myThread(threading.Thread):
    
    def doA(self):
        # lockA.acquire()
        lock.acquire()                  # 加锁        # 为什么在外面加了一把锁后还要在里面再加一把锁
        print(self.name, "gotlockA", time.ctime())
        time.sleep(1)
        # lockB.acquire()
        lock.acquire()                  # 加第二把锁
        print(self.name, "gotlockB", time.ctime())
        # lockB.release()
        lock.release()                  # 释放第一把锁
        # lockA.release()
        lock.release()                  # 释放第二把锁
    
    def doB(self):
        lock.acquire()
        print(self.name, "gotlockB", time.ctime())
        time.sleep(1)
        lock.acquire()
        print(self.name, "gotlockA", time.ctime())
        lock.release()
        lock.release()
    
    def run(self):   # 类似于构造方法
        self.doA()
        self.doB()
    
    
    if __name__ == "__main__":
    
        # lockA = threading.Lock()     # 普通锁
        # lockB = threading.Lock()
        lock = threading.RLock()       # Rlock 叫递归锁,可重用
        threads = []
        for i in range(5):
            threads.append(myThread())
        for t in threads:
            t.start()
        for t in threads:
            t.join()  # 等待线程结束,后面再讲。
    
    
  • 同步锁

        # 加锁后会加锁的部分变成串行
    
    import time
    import threading
    
    def addNum():
        global num  # 在每个线程中都获取这个变量
        print('fuck off')
        # num -= 1          #  此操作的时间远小于CPU切换的时间
    
        # 加锁,被加锁的部分是串行
    
        r.acquire()         #######  加锁
        temp = num          # 1
        # time.sleep(0.001)   # 2 有可能取了数99后,执行完这两步后CPU转到另外的线程上去了,
        print('ok')                    # 另外的线程取到99,执行减1,CPU再转回当前线程,又执行99-1,重复了
        time.sleep(0.0002)
        num = temp - 1
        r.release()         ######## 释放锁
    
    
    
    num = 100
    thread_list = []
    
    r = threading.Lock()    # python的GIL锁
    
    # 用for循环创建100个线程
    for i in range(100):
        t = threading.Thread(target=addNum)
        t.start()
        # t.join()     # join阻塞,可以得到正确的结果,从但是变成了串行,失去了多线程的意义
                       # join虽然可以得到正确结果,但是除了计算的其他部分也会变成并行
        thread_list.append(t)
    
    
    for t in thread_list:
        t.join()
    
    
    print("\nfinal num:", num)
    
    
    # num减1的速度如果
    
    # GIL保证只有一个线程进入解释器
    # 自己加的锁是锁CPU,在我释放锁之前你不要切换了
    
    
  • event

    # event 类似condition
    
    # event.isSet():返回event的状态值;
    #
    # event.wait():如果 event.isSet()==False将阻塞线程;
    #
    # event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
    #
    # event.clear():恢复event的状态值为False。
    
    
    import threading, time
    
    class Boss(threading.Thread):
        def run(self):
            print("BOSS: 今晚大家都要加班到22:00")
            event.is_set() or event.set()
            time.sleep(2)
            print("BOSS:<22:00>可以下班了。 ")
            event.is_set() or event.set()
    
    class Worker(threading.Thread):
        def run(self):
            event.wait()
            print("Worker:哎,命苦啊")
            time.sleep(0.25)
            event.clear()
            event.wait()
            print("Worker: OhYear!")
    
    
    
    
    
    if __name__ == "__main__":
        event = threading.Event()
        threads = []
        for i in range(5):
            threads.append(Worker())
        threads.append(Boss())
        for t in threads:
            t.start()
        for t in threads:
            t.join()
    
    
  • 多线程利器 QUEUE队列

        # 队列里本身就有一把锁
    #
    # import queue, time, threading
    #
    # d = queue.Queue(3)   #
    
    #  d.put('jinxing',0)  #插入数据
    # d.put('xiaohu')
    # d.put('haoran')
    #
    # print(d.get())
    # print(d.get())
    # print(d.get())
    #
    #
    # print(d.qsize())
    
    # li = [1,2,3,4,5]
    #
    # def pri():
    #     while li:
    #         a = li[-1]
    #         print(a)
    #         time.sleep(1)
    #         try:
    #             li.remove(a)
    #         except:
    #             print('----',a)
    #
    # t1 = threading.Thread(target=pri, args=())
    # t1.start()
    # t2 = threading.Thread(target=pri, args=())
    # t2.start()
    
    import threading, queue
    from time import sleep
    from random import randint
    
    
    class Production(threading.Thread):   #  生产者
        def run(self):
            while True:
                r = randint(0, 100)
                q.put(r)
                print("生产出来%s号包子" % r)
                sleep(1)
    
    
    class Proces(threading.Thread):       #  消费者
        def run(self):
            while True:
                re = q.get()
                print("吃掉%s号包子" % re)
                sleep(1)
    
    
    if __name__ == "__main__":
        q = queue.Queue(10)
        threads = [Production(), Production(), Production(), Proces()]
        for t in threads:
            t.start()
    
    

相关文章

  • python多线程

    1.通过threading模块使用多线程 python中多线程的方式是引用threading模块 2.Thread...

  • C# Timer 最简单形象的教程

    System.Threading.Timer System.Threading.Timer是使用多线程时间定时类:...

  • 线程

    多线程--threading python的thread模块是比较底层的模块,python的threading模块...

  • threading

    关于threading模块的多线程的一些实验. threading.Thread 先来看一个最简单的实验多线程的方...

  • 06.系统编程-2.线程

    1、多线程-threading python的thread模块是比较底层的模块,python的threading模...

  • 1.6.1 Python线程使用 -- threading

    多线程-threading python的thread模块是比较底层的模块,python的threading模块是...

  • 线程实战

    多线程-threading python的thread模块是比较底层的模块,python的threading模块是...

  • 多线程

    threading 模块 在 Python 中实现多线程,可以利用 threading 模块中的 Thread 来...

  • Python Threading.Timer 多线程无法退出

    Python Threading.Timer 多线程无法退出

  • 线程 threading

    1. 多线程-threading python的thread模块是比较底层的模块,python的threading...

网友评论

    本文标题:多线程 -- threading

    本文链接:https://www.haomeiwen.com/subject/itjarxtx.html