• python之线程相关操作


    1.线程: 一个进程可以有多个线程,共享一个进程的资源;

    2.进程线程的区别:

       进程是资源分配的最小单位,线程是程序执行的最小单位

    3.python中线程模块threading, 提供的类: Thread, Lock, Rlock, Semaphore, Event, 等等

    4.线程的创建方式

    # 第一种
    # from threading import Thread
    # def f1(s):
    #     print('我是%s' % s)
    # def f2(s):
    #     print('我是%s' % s)
    # 
    # if __name__ == '__main__':
    #     t = Thread(target=f1, args=(1,))
    #     t1 = Thread(target=f1, args=(2,))
    #     t.start()
    #     t1.start()
    #     print('我是主线程')
    
    # 第二种
    from threading import Thread
    
    class MyThread(Thread):
        def __init__(self, name):
            super().__init__()
            self.name = name
        def run(self):
            print('%s今天还是不能皮' % self.name)
    if __name__ == '__main__':
        t = MyThread('Jerry')
        t.start()
        print('主线程')

    6.查看线程的进程id(同进程查看方式一样)

    import os
    from threading import Thread
    def f1(n):
        print('1号', os.getpid())
        print('%s号线程任务' % n)
    def f2(n):
        print('2号', os.getpid())
        print('%s号线程任务' % n)
    if __name__ == '__main__':
        t1 = Thread(target=f1, args=(1,))
        t2 = Thread(target=f2, args=(2,))
        t1.start()
        t2.start()
        print('主线程', os.getpid())
        print('主线程')

    7. 在进程之间数据是空间隔离的, 而在线程中是数据共享的

    import time
    from threading import Thread
    
    #  通过对全局变量的修改来验证线程之间是数据共享的, 共享同一进程中的数据
    num = 100
    def f1():
        time.sleep(3)
        global  num
        num = 3
        print('子线程的num', num)
    
    if __name__ == '__main__':
        t = Thread(target=f1)
        t.start()
        t.join() # 等待子线程运行结束才继续向下执行
        print('主线程的num', num)

    8.多进程和多线程的效率对比

    对于io密集型的, 多线程的时间较快

    def f1():
        time.sleep(1)  #io密集型
        
    if __name__ == '__main__':
        # 查看一下20个线程执行20个任务的执行时间
        t_s_time = time.time()
        t_list = []
        for i in range(5):
            t = Thread(target=f1,)
            t.start()
            t_list.append(t)
        [tt.join() for tt in t_list]
        t_e_time = time.time()
        t_dif_time = t_e_time - t_s_time
        # 查看一下20个进程执行同样的任务的执行时间
        p_s_time = time.time()
        p_list = []
        for i in range(5):
            p = Process(target=f1,)
            p.start()
            p_list.append(p)
        [pp.join() for pp in p_list]
        p_e_time = time.time()
        p_dif_time = p_e_time - p_s_time
        print('多线程的执行时间:', t_dif_time)
        print('多jincheng的执行时间:', p_dif_time)

    计算型:

    import time
    from threading import Thread
    from multiprocessing import Process
    
    def f1():
        # 计算型:
        n = 10
        for i in range(10000000):
            n = n + i
    if __name__ == '__main__':
        # 查看一下20个线程执行20个任务的执行时间
        t_s_time = time.time()
        t_list = []
        for i in range(5):
            t = Thread(target=f1,)
            t.start()
            t_list.append(t)
        [tt.join() for tt in t_list]
        t_e_time = time.time()
        t_dif_time = t_e_time - t_s_time
        # 查看一下20个进程执行同样的任务的执行时间
        p_s_time = time.time()
        p_list = []
        for i in range(5):
            p = Process(target=f1,)
            p.start()
            p_list.append(p)
        [pp.join() for pp in p_list]
        p_e_time = time.time()
        p_dif_time = p_e_time - p_s_time
        print('多线程的执行时间:', t_dif_time)
        print('多jincheng的执行时间:', p_dif_time)

     9.锁,同步,互斥锁 为了保护多线成中数据的完整性和线程间状态的同步.(同进程的锁一样)

     在线程锁中, 会产生死锁现象. 同时抢锁

    import time
    from threading import Thread, Lock, RLock
    def f1(locA, locB):
        # print('xxxx')
        # time.sleep(0.1)
        locA.acquire()
        print('f1>>1号抢到了A锁')
    
        time.sleep(1)
        locB.acquire()
        print('f1>>1号抢到了B锁')
        locB.release()
    
        locA.release()
    def f2(locA, locB):
        print('22222')
        time.sleep(0.1)
        locB.acquire()
        print('f2>>2号抢到了B锁')
        locA.acquire()
        time.sleep(1)
        print('f2>>2号抢到了A锁')
        locA.release()
        locB.release()
    if __name__ == '__main__':
        locA = Lock()
        locB = Lock()
        t1 = Thread(target=f1, args=(locA, locB))
        t2 = Thread(target=f2, args=(locA, locB))
        t1.start()
        t2.start()

      递归锁解决了 死锁现象

    import time
    from threading import Thread, Lock, RLock
    
    def f1(locA, locB):
        print('xxxxx')
        time.sleep(0.1)
        locA.acquire()
        print('f1>>>1号抢到了A锁')
        time.sleep(1)
        locB.acquire()
        print('f1>>>2号抢到了B锁')
        locB.release()
        locA.release()
    def f2(locA, locB):
        print('22222')
        time.sleep(0.1)
        locB.acquire()
        print('f2>>>1号抢到了A锁')
        time.sleep(1)
        locA.acquire()
        print('f2>>>2号抢到了B锁')
        locA.release()
        locB.release()
    if __name__ == '__main__':
        locA = locB = RLock()
        t1 = Thread(target=f1, args=(locA, locB))
        t2 = Thread(target=f2, args=(locB, locA))
        t1.start()
        t2.start()

    10.多线程的程序不结束 和 多进程的程序不结束的区别

    守护进程:主进程代码执行运行结束,守护进程随之结束
    守护线程:守护线程会等待所有非守护线程运行结束才结束
    import time
    from threading import Thread
    from multiprocessing import Process
    
    
    # 守护进程:主进程代码执行运行结束,守护进程随之结束
    # 守护线程:守护线程会等待所有非守护线程运行结束才结束
    def f1():
        time.sleep(2)
        print('一号线程')
    
    def f2():
        time.sleep(3)
        print('二号线程')
    def f3():
        time.sleep(2)
        print('一号进程')
    
    def f4():
        time.sleep(3)
        print('二号进程')
    if __name__ == '__main__':
        # t1 = Thread(target=f1,)
        # t2 = Thread(target=f2,)
        # # t1.daemon = True  #  等非守护线程结束,守护线程才会结束 结果:  主线程结束  一号线程  二号线程
        # t2.daemon = True # 结果: 主线程结束      一号线程
        # t1.start()
        # t2.start()
        # print('主线程结束')
        p1 = Process(target=f3,)
        p2 = Process(target=f4,)
        # p1.daemon = True # 结果: 主进程   二号线程
        p2.daemon= True # 结果: 主进程   一号线程
        p1.start()
        p2.start()
        print('主进程')

    11. GIL锁 :  cpython解释器上的一把互斥锁, Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核

    Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

     
  • 相关阅读:
    骥遇伯乐,关键的一点是人与事的匹配
    好习惯改变一生
    工作中如何面对挫折 [转帖]
    教育心理学领域有一句经典名言
    接触之,熟悉之,打破之
    成年人的35个好习惯(收藏)
    如何树立威信
    人际关系的55个绝招
    人际交往常见几种心理障碍 -实用
    人生成长必须知道的20则故事!
  • 原文地址:https://www.cnblogs.com/q455674496/p/10260446.html
Copyright © 2020-2023  润新知