zoukankan      html  css  js  c++  java
  • python_高级进阶(3)线程

    线程

    进程只是用来把资源集中到一起(进程只是一个资源单位),
    而线程才是cpu上的执行单位。

    线程的好处

    开启进程的开销非常大,比开启线程的开销大很多.
    开启线程的速度非常快.要快几十倍到上百倍.
    线程线程之间可以共享数据,进程与进程之间需借助队列等方法实现通信.

    线程的应用

    该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,
    定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,
    因而不能用多进程。只能在一个进程里并发地开启三个线程,如果是单线程,
    那就只能是,键盘输入时,不能处理文字和自动保存,自动保存时又不能输入和处理文字。

    开启线程两种方式

    方式一

    # 第一种方式
    # from threading import Thread
    # import time
    #
    # def task(name):
    #     print(f'{name} is running')
    #     time.sleep(1)
    #     print(f'{name} is gone')
    #
    #
    #
    # if __name__ == '__main__':
    #
    #     t1 = Thread(target=task,args=('A',))
    #     t1.start()
    #     print('===主线程')  # 线程是没有主次之分的.
    
    

    方式二

     from threading import Thread
    # import time
    #
    # class MyThread(Thread):
    #
    #     def __init__(self,name,l1,s1):
    #         super().__init__()
    #         self.name = name
    #         self.l1 = l1
    #         self.s1 = s1
    #     def run(self):
    #         print(f'{self.name} is running')
    #         time.sleep(1)
    #         print(f'{self.name} is gone')
    #
    # if __name__ == '__main__':
    #     t1 = MyThread('B', [1,2,3], '180')
    #     t1.start()
    #     print('=====主线程')
    
    

    多线程与多进程开启速度区别.

    多进程:

    from threading import Thread
    # from multiprocessing import Process
    # import os
    #
    # def work():
    #     print('hello')
    #
    # if __name__ == '__main__':
    #     #在主进程下开启线程
    #     t=Process(target=work)
    #     t.start()
    #     print('主线程/主进程')
    
    

    多线程

     from threading import Thread
    # import time
    #
    # def task(name):
    #     print(f'{name} is running')
    #     time.sleep(1)
    #     print(f'{name} is gone')
    #
    #
    #
    # if __name__ == '__main__':
    #
    #     t1 = Thread(target=task,args=('海狗',))
    #     t1.start()
    #     print('===主线程')  # 线程是没有主次之分的.
    
    

    线程进程

    多进程:

    # from multiprocessing import Process
    # import time
    # import os
    # def task(name):
    #     print(f'子进程: {os.getpid()}')
    #     print(f'主进程: {os.getppid()}')
    #
    #
    # if __name__ == '__main__':
    #
    #     p1 = Process(target=task,args=('A',))  # 创建一个进程对象
    #     p2 = Process(target=task,args=('A',))  # 创建一个进程对象
    #     p1.start()
    #     p2.start()
    #     print(f'==主{os.getpid()}')
    
    

    多线程

     
    from threading import Thread
    import os
    
    def task():
        print(os.getpid())
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
        print(f'===主线程{os.getpid()}')
    
    

    同一个进程内线程共享内部数据

    # from threading import Thread
    # import os
    #
    # x = 3
    # def task():
    #     global x
    #     x = 100
    #
    # if __name__ == '__main__':
    #
    #     t1 = Thread(target=task)
    #     t1.start()
    #     t1.join()
    #     print(f'===主线程{x}')
    
    # 同一进程内的资源数据对于这个进程的多个线程来说是共享的.
    
    

    线程的相关其他方法

    
    from threading import Thread
    from threading import currentThread
    from threading import enumerate
    from threading import active_count
    import os,time
    x=3
    def task():
        time.sleep(1)
        print('123456')
    if __name__=="__main__":
        t1=Thread(target=task,name='线程1')
        t2= Thread(target=task, name='线程2')
        t1.start()
        t2.start()
        # time.sleep(2)
        # print(t1.isAlive())#判断t1线程是否活着
        # print(t1.getName())#获取t1线程名字
        # t1.setName('子线程1')#修改名字
        # print(t1.name)#获取线程名字
        #threading方法
        print(currentThread())#获取当前线程的对象
        print(enumerate())#返回一个列表包含所有线程的对象
        print(active_count())#获取线程数
        print(f'++++主线程{os.getpid()}')
    

    互斥锁程

    from threading import Thread
    # import time
    # import random
    # x = 100
    #
    # def task():
    #     time.sleep(random.randint(1,2))
    #     global x
    #     temp = x
    #     time.sleep(random.randint(1, 3))
    #     temp = temp - 1
    #     x = temp
    #
    #
    # if __name__ == '__main__':
    #     l1 = []
    #     for i in range(100):
    #         t = Thread(target=task)
    #         l1.append(t)
    #         t.start()
    #
    #     for i in l1:
    #         i.join()
    #     print(f'主线程{x}')
    
    # 多个任务公抢一个数据,保证数据的安全的目的,要让其串行
    
    
    from threading import Thread
    from threading import Lock
    import time
    import random
    x = 100
    
    def task(lock):
    
        lock.acquire()
        # time.sleep(random.randint(1,2))
        global x
        temp = x
        time.sleep(0.01)
        temp = temp - 1
        x = temp
        lock.release()
    
    
    if __name__ == '__main__':
        mutex = Lock()
        l1 = []
        for i in range(100):
            t = Thread(target=task,args=(mutex,))
            l1.append(t)
            t.start()
    
        time.sleep(3)
        print(f'主线程{x}')
    
    

    守护线程

    join: 阻塞 告知主线程要等待我子线程执行完毕之后再执行主线程
    
    # from threading import Thread
    # import time
    #
    # def task(name):
    #     print(f'{name} is running')
    #     time.sleep(1)
    #     print(f'{name} is gone')
    #
    #
    #
    # if __name__ == '__main__':
    #     start_time = time.time()
    #     t1 = Thread(target=task,args=('海狗',))
    #     t2 = Thread(target=task,args=('海狗1',))
    #     t3 = Thread(target=task,args=('海狗2',))
    #
    #     t1.start()
    #     t1.join()
    #     t2.start()
    #     t2.join()
    #     t3.start()
    #     t3.join()
    #
    #     print(f'===主线程{time.time() - start_time}')  # 线程是没有主次之分的.
    
    
    # 守护线程
    
    # 回忆一下守护进程
    
    # from multiprocessing import Process
    # import time
    #
    #
    # def foo():
    #     print(123)
    #     time.sleep(1)
    #     print("end123")
    #
    #
    # def bar():
    #     print(456)
    #     time.sleep(2)
    #     print("end456")
    #
    # if __name__ == '__main__':
    #
    #     p1 = Process(target=foo,)
    #     p2 = Process(target=bar,)
    #
    #     p1.daemon = True
    #     p1.start()
    #     p2.start()
    #     print('====主')
    
    
    
    # 守护线程
    
    # from threading import Thread
    # import time
    #
    #
    # def sayhi(name):
    #     print('你滚!')
    #     time.sleep(2)
    #     print('%s say hello' %name)
    #
    # if __name__ == '__main__':
    #     t = Thread(target=sayhi,args=('egon',))
    #     # t.setDaemon(True) #必须在t.start()之前设置
    #     t.daemon = True
    #     t.start()  # 线程的开启速度要跟进程开很多
    #
    #     print('主线程')
    
    
    
    # from threading import Thread
    # import time
    #
    # def foo():
    #     print(123)  # 1
    #     time.sleep(1)
    #     print("end123")  # 4
    #
    # def bar():
    #     print(456)  # 2
    #     time.sleep(3)
    #     print("end456")  # 5
    #
    #
    # t1=Thread(target=foo)
    # t2=Thread(target=bar)
    #
    # t1.daemon=True
    # t1.start()
    # t2.start()
    # print("main-------")  # 3
    
    
    # 主线程什么时候结束???
    # 守护线程 等待非守护子线程以及主线程结束之后,结束.
    # from threading import Thread
    # import time
    #
    # def foo():
    #     print(123)  # 1
    #     time.sleep(3)
    #     print("end123")  # 4
    #
    # def bar():
    #     print(456)  # 2
    #     time.sleep(1)
    #     print("end456")  # 5
    #
    #
    # t1=Thread(target=foo)
    # t2=Thread(target=bar)
    #
    # t1.daemon=True
    # t1.start()
    # t2.start()
    # print("main-------")  # 3
    '''
    123
    456
    main-------
    end123
    end456
    '''
    
    # from threading import Thread
    # import time
    #
    # def foo():
    #     print(123)
    #     time.sleep(3)
    #     print("end123")
    #
    # def bar():
    #     print(456)
    #     time.sleep(1)
    #     print("end456")
    #
    #
    # t1=Thread(target=foo)
    # t2=Thread(target=bar)
    #
    # t1.daemon=True
    # t1.start()
    # t2.start()
    # print("main-------")
    
    
  • 相关阅读:
    JDBC 详解
    Class.forName() 详解
    23种设计模式
    MVC 模式
    Ant 打包 问题
    Jedis操作Redis--SortedSet类型 (会自然排序)
    在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案
    在idea中使用@Test注解报错的解决方案
    判断返回的对象是否为空
    使用标准的日期格式化过程
  • 原文地址:https://www.cnblogs.com/SkyRabbit/p/11396592.html
Copyright © 2011-2022 走看看