• 线程相关内容


    1.线程: 是cpu执行程序的最小单元,一份进程中可以包含多个线程,开辟线程时无需重新分配资源,子线程跟主线程共享资源。

    from multiprocessing import Process
    from threading import Thread
    import time
    # 进程并发
    def func(i):
        print(i)
    
    if __name__ == "__main__":
        lst = []
        time1 = time.time()
        for i in range(100):
            p = Process(target=func,args=(i,))
            p.start()
            lst.append(p)
        for j in lst:
            j.join()
        time2 = time.time()
        print(time2-time1) # 2.086568593978882
    
    
    
    from multiprocessing import Process
    from threading import Thread
    import time
    # 线程并发
    def func(i):
        print(i)
    
    if __name__ == "__main__":
        lst = []
        time1 = time.time()
        for i in range(100):
            t = Thread(target=func,args=(i,))
            t.start()
            lst.append(t)
        for j in lst:
            j.join() # 线程也是异步的
        time2 = time.time()
        print(time2-time1) # 0.01492619514465332  因无需再分配资源,所以线程速度大大快于进程

    1.1  线程之间共享数据

    from threading import Thread
    a = 100
    def func():
        global a
        a -= 1
    if __name__ == "__main__":
        for i in range(10):
            t = Thread(target=func)
            t.start()
        print(a) # 90

    1.2  用类定义线程

    from threading import Thread
    class Mythread(Thread):
        def __init__(self,args):
            self.args = args
            super().__init__() # 若有参数则要通过super()调父类里面的init方法
        def run(self): # 必须命名为run()方法
            print("用类定义的线程",self.args)
    
    if __name__ == "__main__":
        t = Mythread(888)
        t.start() # 用类定义的线程 888

    1.3  线程相关的函数

    from threading import Thread
    import time
    def func():
        time.sleep(1)
        print(111)
    
    # (1) is_alive(): 判断线程是否还存在
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        res = t.is_alive()
        print(res) # True
    
    
    # (2) setName():设置线程的名字
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        t.setName("8号")
        print(t) # <Thread(8号, started 5880)>
    
    
    # (3) getName(): 获取线程名字
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        t.setName("8号")
        print(t.getName()) # 8号
    
    
    # (4) currentThread().ident:查看线程id号
    from threading import currentThread #需要引入currentThread
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        res = currentThread().ident
        print(res) # 3380
    
    
    # (5) enumerate():返回正在运行的线程列表
    from threading import enumerate
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        lst = enumerate()
        print(lst) # [<_MainThread(MainThread, started 9096)>, <Thread(Thread-1, started 14956)>]
    
    
    # (6) activeCount():返回正在运行的线程数量
    from threading import enumerate,activeCount
    if __name__ == "__main__":
        t = Thread(target=func)
        t.start()
        res = activeCount() # 方式一
        print(res) # 2
        lst = enumerate() # 方式二
        print(len(lst)) # 2

    1.4 守护线程:守护的是所有的子线程,等所有子线程都执行完后,守护线程也会被终止

    from threading import Thread
    import time
    def func1():
        time.sleep(0.5)
        print("老二,你结束没?")
        time.sleep(0.5)
        print("我要关掉了")
    
    def func2():
        time.sleep(1.5)
        print("大哥,等我一会")
        time.sleep(1)
    
    if __name__ == "__main__":
        t1 = Thread(target=func1)
        t1.setDaemon(True)
        t1.start()
        t2 = Thread(target=func2)
        t2.start()
        t2.join()
        print("臭小子,还有你们的老父亲我呢")
        time.sleep(1)
        print("OK,回家")
    # 在主线程和func2都结束后,func1结束,程序结束

    1.5 Lock:上锁,保护数据安全

    from threading import Thread,Lock
    import time
    money = 1000000
    def func(lock):
        global money
        with lock:
            for i in range(100000):
                money -= 1
    
    if __name__ == "__main__":
        lock = Lock()
        lst = []
        for i in range(10):
            t = Thread(target=func,args=(lock,))
            t.start()
            lst.append(t)
        print("败家子儿,我的一百万,被你们折腾得就剩{}了".format(money))
        for j in lst:
            j.join()
        print("败家子儿,我的一百万,被你们折腾得就剩{}了".format(money))
        print("还不赶紧还给我")
    
    def func(lock):
        global money
        with lock:
            for i in range(100000):
                money += 1
    
    if __name__ == "__main__":
        lock = Lock()
        lst = []
        for i in range(10):
            t = Thread(target=func,args=(lock,))
            t.start()
            lst.append(t)
        print("还给你,有啥了不起,给你{}".format(money))
        for j in lst:
            j.join()
        print("对,都还给你,{}元".format(money))

    1.6 信号量Semaphore: 线程中控制锁的数量

    from threading import Thread,Semaphore
    import time
    def func(sem,i):
        sem.acquire()
        print("这是"+str(i))
        time.sleep(1)
        sem.release()
    
    if __name__ == "__main__":
        sem = Semaphore(3)
        for i in range(10):
            t = Thread(target=func,args=(sem,i))
            t.start()
    
    
    # with语法
    from threading import Thread,Semaphore
    import time
    def func(i):
    
        with sem:
            print("给我食物,给我钱")
            print(i)
            time.sleep(2)
    
    if __name__ == "__main__":
        sem = Semaphore(2)
        lst1 = []
        lst = ["肉包子", "200万", "排骨汤", "腊肠", "腊鱼", "花生米", "酸菜鱼", "100万"]
        for i in lst:
            t = Thread(target=func,args=(i,))
            t.start()
            lst1.append(t)
        for j in lst1:
            j.join()

    1.7: 线程的缺陷

    python中的线程可以并发,但是不能并行(同一个进程下的多个线程不能分开被多个cpu同时执行)
    原因:
    全局解释器锁(Cpython解释器特有) GIL锁:同一时间,一个进程下的多个线程只能被一个cpu执行
    python是解释型语言,执行一句编译一句,而不是一次性全部编译成功,不能提前规划,都是临时调度
    容易造成cpu执行调度异常.所以加了一把锁叫GIL

    想要并行的解决办法:
    (1)用多进程间接实现线程的并行
    (2)换一个Pypy,Jpython解释器

    程序分为计算密集型和io密集型
    对于计算密集型程序会过度依赖cpu,但网页,爬虫,OA办公,这种io密集型的程序里,python绰绰有余

  • 相关阅读:
    [2020.11.15]CCPC Final 2019
    [2020.11.13]UOJ#424. 【集训队作业2018】count
    [2020.11.13]AtCoder Japan Alumni Group Summer Camp 2018 Day 2 K
    [2020.11.13]CF704C Black Widow
    [2020.11.13]CF765F Souvenirs
    [2020.11.13]AGC035D
    [2020.11.10]CSPS2020 翻车记
    拉格朗日反演(暂时鸽)与CF1349F2(xtq F2)
    [2020.6.20]ZJOI2020 Day1游记
    [2020.5.22]UOJ523 【美团杯2020】半前缀计数
  • 原文地址:https://www.cnblogs.com/fdsimin/p/13094002.html
Copyright © 2020-2023  润新知