zoukankan      html  css  js  c++  java
  • 并发编程-线程

    一、什么是线程

      1.进程、线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物

      进程:资源单位

      线程:执行单位

        将内存比如工厂

        那么进程就相当于是工厂里面的车间

        而你的线程就相当于是车间里面的流水线

      ps:每一个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中提供代码运行锁需要的资源

      2.为什么要有线程:

        开进程:

          申请内存空间耗资源

        开线程:

          一个进程内可以起多个线程,并且线程与线程之间数据是共享的

        ps:开启线程的开销要远远小于开启进程的开销

    二、创建线程的两种方式:

      1.用类继承

    from threading import Thread
    import time
    
    # 创建线程的方式二
    class MyThread(Thread):
        def __init__(self,name):
            super().__init__()
            self.name = name
    
        def run(self):
            print('1 run')
            time.sleep(1)
            print('1 run over')
    
    t = MyThread('tom')
    t.start()
    print('2')

      2.直接调用

    from threading import Thread
    import time
    
    # 创建线程的方式一
    def task(name):
        print('1 run')
        time.sleep(1)
        print('1 run over')
    # 开线程不需要在__main__代码块内,但是习惯性的还是写在__main__代码块内
    t = Thread(target=task,args=('tom',))
    t.start()  # 告诉操作系统开辟一个线程,线程的开销内存远远小于进程
    # 小到代码执行完,线程就已经开启了
    print('2')

    三。线程对象及其他方法:

      current_thread(),name 获取线程名

      os.getpid() 获取子线程ID

      .join() 主线程等待子线程运行完毕

      active_count() 当前正在活跃的线程数

    四:守护线程:

    from threading import Thread,current_thread
    import time
    
    
    
    def task(i):
        print(current_thread().name)
        time.sleep(i)
        print('GG')
    for i in range(3):
        t = Thread(target=task,args=(i,))
        t.start()
    # t = Thread(target=task,args=(1,))
    # t.daemon = True
    # t.start()
    print('')
    # 主线程运行结束之后需要等待子线程结束才能结束呢?
    """
    主线程的结束也就意味着进程的结束
    主线程必须等待其他非守护线程的结束才能结束
    (意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)
    """

    五:线程间通信

      因为在同一块内存空间,可实现通信

    from threading import Thread
    
    
    money = 666
    
    def task():
        global money
        money = 999
    
    t = Thread(target=task)
    t.start()
    t.join()
    print(money)
    代码验证

    六:互斥锁

      多个线程修改同一份数据会造成数据错乱的问题 所以需要加锁
      保证了数据的安全 但是降低了代码的运行效率 因为你将并发变成了串行
      ps:针对不同的数据 应该加不同的锁进行处理
      抢锁 acquire()
      释放锁 release()

    from threading import Thread, Lock
    import time
    
    n = 100
    
    
    def task():
        global n
        # mutex.acquire()
        tmp = n
        time.sleep(0.1)
        n = tmp - 1
        # mutex.release()
    
    
    t_list = []
    # mutex = Lock()
    for i in range(100):
        t = Thread(target=task, )
        t.start()
        t_list.append(t)
    
    for t in t_list:
        t.join()
    print(n)
    View Code
  • 相关阅读:
    Mysql多实例配置
    Mysql多实例主从复制
    粪发涂墙-321
    粪发涂墙-123
    SpringCloud-粪发涂墙90
    线上BUG定位神器(阿尔萨斯)-Arthas2019-0801
    confluence-工具安装
    新应用启动之类冲突-2019-7-26
    新项目组之应用启动-2019-07-25
    新装虚拟机-2019-07-24日记
  • 原文地址:https://www.cnblogs.com/xiaowangba9494/p/11342216.html
Copyright © 2011-2022 走看看