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

    线程实现

    python 的 thread 模块是比较底层的模块,threading 模块是对 thread 做了一些封装的,可以更好的使用

    说明:python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。而创建自己的线程实例后,通过Thread类的start方法,可以启动该线程,交给python虚拟机进行调度,当该线程获得执行的机会时,就会调用run方法执行线程

    多线程执行

    # coding=utf-8
    import threading
    import time
    
    
    class HelloWorld(threading.Thread):
        def run(self):
            print(f"hello, world ~, my name is{self.name}")
            time.sleep(1)
    
    
    if __name__ == '__main__':
        for i in range(5):
            hello_obj = HelloWorld()
            hello_obj.start()
    View Code

    可以看到同时打印了 hello, world ~,还有自己的 name(Thread-id);当调用 start() 时,才会真正的创建线程,并且开始执行

    主线程会等待所有的子线程结束后才结束

    # coding=utf-8
    import threading
    import time
    
    
    class HelloWorld(threading.Thread):
        def __init__(self, num):
            threading.Thread.__init__(self)
            self.second = num
    
        def run(self):
            print(f"hello, world ~, my name is{self.name}")
            time.sleep(self.second)
    
    
    if __name__ == '__main__':
        for i in range(5):
            hello_obj = HelloWorld(i)
            hello_obj.start()
        while True:
            # 查看当前运行的线程数量
            length = len(threading.enumerate())
            print(f"current running thread num is:{length}")
            if length <= 3:
                break
            time.sleep(1)
    View Code

    总结:

    1. 每个线程默认有一个名字,尽管上面的例子中没有指定线程对象的name,但是python会自动为线程指定一个名字
    2. 当线程的run()方法结束时该线程完成
    3. 无法控制线程调度顺序,但可以通过别的方式来影响线程调度的方式

    多线程-共享全局变量

    在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据

    缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)

    from threading import Thread
    import time
    
    g_num = 100
    
    
    class Work1(Thread):
        def run(self):
            global g_num
            for i in range(3):
                g_num += 1
    
            print(f"----in work1, g_num is {g_num}---")
            
    
    class Work2(Thread):
        def run(self):
            global g_num
            print(f"----in work2, g_num is {g_num}---")
    
    
    print(f"---线程创建之前g_num is {g_num}---")
    
    t1 = Work1()
    t1.start()
    
    # 延时一会,保证t1线程中的事情做完
    time.sleep(1)
    
    t2 = Work2()
    t2.start()
    View Code

    多线程开发可能遇到的问题

    假设两个线程 t1 和 t2 都要对全局变量 g_num (默认是0)进行加1运算,t1 和 t2 都各对 g_num 加10次,g_num 的最终的结果应该为 20

    但是由于是多线程同时操作,有可能出现下面情况:

    1. 在 g_num=0 时,t1 取得 g_num=0。此时操作系统把 t1 调度为”sleeping”状态,把 t2 转换为”running”状态,t2 也获得 g_num=0
    2. 然后 t2 对得到的值进行加1并赋给 g_num,使得 g_num=1
    3. 然后操作系统又把 t2 调度为”sleeping”,把 t1 转为”running”,线程 t1 又把它之前得到的0加1后赋值给 g_num
    4. 这样导致虽然 t1 和 t2 都对 g_num 加1,但结果仍然是 g_num=1
      # coding=utf-8
      import time
      import threading
      from threading import Thread
      
      g_num = 0
      
      
      class Work1(Thread):
          def __init__(self, count):
              Thread.__init__(self)
              self.count = count
      
          def run(self):
              global g_num
              for i in range(self.count):
                  g_num += 1
              # print(f"----in work1, g_num is {g_num}---")
      
      
      class Work2(Work1):
          pass
      
      
      print(f"---线程创建之前g_num is {g_num}---")
      
      count = 1000000
      
      t1 = Work1(count)
      t1.start()
      
      t2 = Work2(count)
      t2.start()
      
      while len(threading.enumerate()) != 1:
          time.sleep(1)
      
      print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
      
      运行结果
      ---线程创建之前g_num is 0---
      2个线程对同一个全局变量操作之后的最终结果是:1275729
      View Code

     如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确

       

    每天都要遇到更好的自己.
  • 相关阅读:
    转:Intellij idea创建javaWeb以及Servlet简单实现
    IntelliJ IDEA控制台启动Tomcat输出中文乱码问题
    Tomcat 输出日志出现中文乱码
    转:Java Web 项目发布到Tomcat中三种部署方法
    运行tomcat7w.exe提示指定的服务未安装 解决办法
    (转)ASP.NET MVC:Razor 引入命名空间
    (转)解决WinDbg调试Dump文件不同环境mscordacwks.dll版本问题
    svn移动目录时如何保留原来的日志
    Memcached 教程
    最近帮朋友写了一个百度竞价关键词快速分词(分组)工具,支持与或逻辑分组,附源码和工具下载链接
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/10841008.html
Copyright © 2011-2022 走看看