zoukankan      html  css  js  c++  java
  • Python多线程编程,线程锁

    多线程

    • 什么是线程?

      1. 线程也是一种多任务的编程方法,可以利用计算机多核资源完成程序的并发运行。
      2. 线程又被称为轻量级进程
    • 线程的特征

      1. 线程是计算机多核分配的最小单位
      2. 一个进程可以包含多个线程
      3. 线程也是一个运行的过程,消耗计算机资源,多个线程共享进程的资源和空间
      4. 线程的创建删除消耗的资源都远远比进程小
      5. 多个线程之间执行互不干扰
      6. 线程也有自己的特有属性,比如指令集ID

    threading 模块创建线程

    • t=threading.Thread()

      • 功能:创建线程对象

      • 参数

        • name:线程名称,如果为空则为默认值,Tread-1,Tread-2,Tread-3
        • target:线程函数
        • args:元组,给线程函数按照位置传参
        • kwargs:字典,给县城函数按照键值传参
    • t.start():启动线程,自动运行线程函数

    • t.join([timeout]):回收进程

    • t.is_alive():查看线程状态

    • t.name():查看线程名称

    • t.setName():设置线程名称

    • t.daemon属性:默认主线成退出不影响分支线程继续执行,如果设置为True则分支线程随着主线程一起退出

      • 设置方法

        • t.daemon = True

        • t.setDaemon(Ture)

           
    •  1 #!/usr/bin/env python3
       2 from threading import Thread
       3 from time import sleep
       4 import os
       5  6 # 创建线程函数
       7 def music():
       8     sleep(2)
       9     print("分支线程")
      10 11 t = Thread(target = music)
      12 # t.start()   # ******************************
      13 print("主线程结束---------")
      14 15 '''没有设置的打印结果
      16 主线程结束---------
      17 分支线程
      18 '''
      19 20 '''设置为True打印结果
      21 主线程结束---------
      22 '''
    • threading.currentThread:获取当前线程对象

    @此处代码示意子线程共享同一个进程内的变量

     
     1   #!/usr/bin/env python3
     2   from threading import Thread
     3   from time import sleep
     4   import os
     5   
     6   # 创建线程函数
     7   def music():
     8       global a
     9       print("a=",a)
    10       a = 10000
    11       for i in range(5):
    12           sleep(1)
    13           print("1212")
    14   
    15   a = 1
    16   t = Thread(target = music)
    17   t.start()
    18   t.join()
    19   print("主线程的a =",a)

    创建自己的线程类

    考察点:类的使用,调用父类的__init__方法,函数*传参和**传参

      
     1  
     2   
     3 from threading import Thread
     4 import time
     5  6 class MyThread(Thread):
     7     name1 = 'MyThread-1'
     8     def __init__(self,target,args=(), kwargs={}, name = 'MyThread-1'):
     9         super().__init__()
    10         self.name = name
    11         self.target = target
    12         self.args = args
    13         self.kwargs = kwargs
    14     def run(self):
    15         self.target(*self.args,**self.kwargs)
    16 17 def player(song,sec):
    18     for i in range(2):
    19         print("播放 %s:%s"%(song,time.ctime()))
    20         time.sleep(sec)
    21 22 t =MyThread(target = player, args = ('亮亮',2))
    23 24 t.start()
    25 t.join()
    26

    线程通信

    通信方法:由于多个线程共享进程的内存空间,所以线程间通信可以使用全局变量完成

    注意事项:线程间使用全局变量往往要同步互斥机制保证通信的安全

    线程同步互斥方法

    • event

    • e = threading.Event():创建事件对象

    • e.wait([timeout]):设置状态,如果已经设置,那么这个函数将阻塞,timeout为超时时间

    • e.set:将e变成设置状态

    • e.clear:删除设置状态

        
    import threading
    from time import sleep
    
    def fun1():
        print("bar拜山头")
        global s
        s = "天王盖地虎"
    
    def fun2():
        sleep(4)
        global s
        print("我把限制解除了")
        e.set()     # 解除限制,释放资源
    
    def fun3():
        e.wait() # 检测限制
        print("说出口令")
        global s
        if s == "天王盖地虎":
            print("宝塔镇河妖,自己人")
        else:
            print("打死他")
        s = "哈哈哈哈哈哈"
    
    # 创建同步互斥对象
    e = threading.Event()
    # 创建新线程
    f1 = threading.Thread(target = fun1)
    f3 = threading.Thread(target = fun3)
    f2 = threading.Thread(target = fun2)
    # 开启线程
    f1.start()
    f3.start()
    f2.start()
    #准备回收
    f1.join()
    f3.join()
    f2.join()

    线程锁

    • lock = threading.Lock():创建锁对象
    • lock.acquire():上锁
    • lock.release():解锁

    也可以用过with来上锁

      
    1 with lock:
    2     ...
    3     ...

     

    @需要了解!!!

    • Python线程的GIL问题(全局解释器)

      python---->支持多线程---->同步互斥问题---->加锁解决---->超级锁(给解释器加锁)---->解释器同一时刻只能解释一个线程--->导致效率低下

    • 后果

      一个解释器同一时刻只能解释执行一个线程,所以导致Python线程效率低下,但是当遇到IO阻塞时线程会主动让出解释器,因此Pyhton线程更加适合高延迟的IO程序并发

    • 解决方案

      • 尽量使用进程完成并发(和没说一样)
      • 不适当用C解释器 (用C# ,JAVA)
      • 尽量使用多种方案组合的方式进行并发操作,线程用作高延迟IO
    作者:Banl
    ----------------------------------------------------------------------

    个性签名:青春用来挥霍,白头不知所措!

    如果这篇文章对你有些帮助,记得在右下角点个“推荐”,拜谢!

  • 相关阅读:
    VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布 Inchroy's Blog 博客频道 CSDN.NET
    编写可丢弃的代码
    c++ using namespace std; 海明威 博客园
    解决MySQL server has gone away
    nginx upstream 调度策略
    (2006, 'MySQL server has gone away') 错误解决 dba007的空间 51CTO技术博客
    Linux IO模型漫谈(2) 轩脉刃 博客园
    redis源码笔记 initServer 刘浩de技术博客 博客园
    MySQLdb批量插入数据
    词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/BanL/p/9642471.html
Copyright © 2011-2022 走看看