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

    多线程

    什么是线程

    进程是操作系统调度以及进行资源分配的基础单位,是一个资源单位

    线程是操作系统可以运算调度的最小单位,是真正的执行单位,其包含在进程中,一个线程就是一条固定的控制流程。

    • 一个进程可以包含多个线程,同一进程中的线程共享进程内的资源

    • 特点:系统会为每一个进程自动创建一条线程,称之为主线程,后续通过代码开启的线程称之为子线程(并不是父子关系,只是这么称呼)

    进程对比线程

    1. 进程是一个资源单位,线程是执行单位

    2. 创建进程的开销远大于线程

    3. 多个进程之间内存是相互隔离的,而线程是共享进程内的所有资源

    4. 进程之间是竞争关系,线程是协作关系

    5. 进程之间有层级关系,而线程之间没有

    开启线程也是需要消耗资源的

    如果把计算机比喻成一个工厂,那么进程可以看做一个车间,而线程则是流水线

    为什么要用线程

    1. 有多个任务要并发处理
    2. 当要并发的任务量大的时候,不能使用进程(资源开销大)

    CPython的全局锁

    使用线程的方法

    和使用进程类似,因为本身就是先创造进程,后来发现进程的资源消耗太高,才有的线程,而线程也是继承与进程的

    • 方法一:实例化对象
    from threading  import Thread
    
    def task():
        print("bar run")
    
    # 与进程不同之处1   不需要加判断 开启线程的代码放哪里都可以,因为他不会导入这个文件
    t = Thread(target=task)
    t.start()
    print("over")
    
    • 方法二:继承

    • 和线程一样,在需要高度自定义的时候使用

    from threading import Thread
    
    class MyThread(Thread):
    
        def run(self):
            # 把要在子线中执行的代码放入run中
            print("bar run")
    
    mt = MyThread()
    mt.start()
    print("over")
    

    线程安全问题

    • 只要你并发的访问了同一个资源,就一定会产生安全问题,线程的解决方案和进程一直,就是给操作公共资源的代码加锁
    • 线程间可以访问数据
    from threading import Thread,Lock
    import time
    a = 10
    
    l = Lock()
    
    def task():
        global a
        l.acquire()
        temp = a
        time.sleep(0.1)
        a = temp - 1
        l.release()
    
    ts = []
    for i in range(10):
        t = Thread(target=task)
        t.start()
        ts.append(t)
    for t in ts:t.join()
    
    print(a)
    
    0
    

    守护线程

    概念同进程

    默认情况下,主线程即使代码执行完毕,也会等待所有非守护线程完毕后程序才能结束 因为多个线程之间是协作关系 。

    from threading import Thread
    import time
    
    def task1():
        print('t1开始了')
        time.sleep(5)
        print('t1结束了')
        
    def task2():
    	print('t2开始了')
    	time.sleep(3)
    	print('t2结束了')
        
    print('主开始了哦')
    
    t1 = Thread(target=task1)
    t2 = Thread(target=task2)
    
    t1.daemon = True
    
    t1.start()
    t2.start()
    
    print('主结束了哦')
    
    
    主开始了哦
    t1开始了
    t2开始了
    主结束了哦
    t2结束了
    

    线程中的常用属性和方法

    from threading import  Thread,currentThread,enumerate,activeCount
    import time
    
    # t = Thread()
    # t.start()
    # t.join()
    # t.is_alive()	# 是否存活
    # t.isAlive()	# 和上面一样,只是写法是小驼峰为了照顾其他程序员
    # t.ident  # 线程标识符   id
    # t.daemon
    
    # 获取当前线程对象
    # print(currentThread())	# <_MainThread(MainThread, started 6732)>
    # t = Thread(target=lambda :print(currentThread()))	# <Thread(Thread-1, started 848)>
    
    # 线程可以用lambda,进程不可以
    t = Thread(target=lambda :time.sleep(1))
    t.start()
    
    t = Thread(target=lambda :time.sleep(1))
    t.start()
    # 获取正在运行的所有线程对象  是一个列表
    print(enumerate())	# 三个进程的列表,主进程和两个子进程
    
    # 存活的线程数量
    print(activeCount())	# 3
    
  • 相关阅读:
    MapReduce-shuffle过程详解
    YARN中的失败分析
    HBase协处理器的使用(添加Solr二级索引)
    Flume具体应用(多案例)
    Flume架构及运行机制
    python Cmd实例之网络爬虫应用
    mongodb3 权限认证问题总结
    webpack配置
    apt软件包管理
    python笔记之编程风格大比拼
  • 原文地址:https://www.cnblogs.com/lucky75/p/11134842.html
Copyright © 2011-2022 走看看