zoukankan      html  css  js  c++  java
  • python note 31 多线程

    1、应用程序

    import threading
    
    print('666')
    
    def func(arg):
        print(arg)
    
    
    t = threading.Thread(target=func)
    t.start()
    
    print('end')

    2、线程的使用

    import threading
    
    1.线程的基本使用
    def func(arg):
        print(arg)
    
    t = threading.Thread(target=func,args=(11,))
    t.start()
    
    print(123)
    2.主线程默认等子线程执行完毕
    import time
    def func(arg):
        time.sleep(arg)
        print(arg)
    
    t1 = threading.Thread(target=func,args=(3,))
    t1.start()
    
    t2 = threading.Thread(target=func,args=(9,))
    t2.start()
    
    print(123)
    3.主线程不再等,主线程终止则所有子线程终止
    import time
    def func(arg):
        time.sleep(2)
        print(arg)
    
    t1 = threading.Thread(target=func,args=(3,))
    t1.setDaemon(True)
    t1.start()
    
    t2 = threading.Thread(target=func,args=(9,))
    t2.setDaemon(True)
    t2.start()
    
    print(123)
    
    4.开发者可以控制主线程等待子线程(最多等待时间) 
    import time
    def func(arg):
        time.sleep(0.01)
        print(arg)
    
    print('创建子线程t1')
    t1 = threading.Thread(target=func,args=(3,))
    t1.start()
    # 无参数,让主线程在这里等着,等到子线程t1执行完毕,才可以继续往下走。
    # 有参数,让主线程在这里最多等待n秒,无论是否执行完毕,会继续往下走。
    t1.join(2)
    
    print('创建子线程t2')
    t2 = threading.Thread(target=func,args=(9,))
    t2.start()
    t2.join(2) # 让主线程在这里等着,等到子线程t2执行完毕,才可以继续往下走。
    
    print(123)
    
    4.线程名称
    def func(arg):
        # 获取当前执行该函数的线程的对象
        t = threading.current_thread()
        # 根据当前线程对象获取当前线程名称
        name = t.getName()
        print(name,arg)
    
    t1 = threading.Thread(target=func,args=(11,))
    t1.setName('侯明魏')
    t1.start()
    
    t2 = threading.Thread(target=func,args=(22,))
    t2.setName('刘宁钱')
    t2.start()
    
    print(123)
    
    5.线程本质
    # 先打印:11?123?
    def func(arg):
        print(arg)
    
    t1 = threading.Thread(target=func,args=(11,))
    t1.start()
    # start 是开始运行线程吗?不是
    # start 告诉cpu,我已经准备就绪,你可以调度我了。
    print(123)
    
    
    6.补充:面向对象版本的多线程 
    # 多线程方式:1 (常见)
    def func(arg):
        print(arg)
    
    t1 = threading.Thread(target=func,args=(11,))
    t1.start()
    
    # 多线程方式:2
    class MyThread(threading.Thread):
    
    def run(self):
        print(11111,self._args,self._kwargs)
    
    t1 = MyThread(args=(11,))
    t1.start()
    
    t2 = MyThread(args=(22,))
    t2.start()
    
    print('end')

    3、多线程

    import threading
    
    1. 计算密集型多线程无用
    v1 = [11,22,33] # +1
    v2 = [44,55,66] # 100
    
    def func(data,plus):
        for i in range(len(data)):
            data[i] = data[i] + plus
    
    t1 = threading.Thread(target=func,args=(v1,1))
    t1.start()
    
    t2 = threading.Thread(target=func,args=(v2,100))
    t2.start()
    
    
    2. IO操作 多线程有用
    import threading
    import requests
    import uuid
    
    url_list = [
         'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg',
         'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg',
         'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg',
     ]
    
    def task(url):
        ret = requests.get(url)
        file_name = str(uuid.uuid4()) + '.jpg'
        with open(file_name, mode='wb') as f:
            f.write(ret.content)
    
    for url in url_list:
    
        t = threading.Thread(target=task,args=(url,))
        t.start()

    4、多线程的问题

    # by luffycity.com
    import time
    import threading
    
    lock = threading.RLock()
    
    n = 10
    
    def task(i):
        print('这段代码不加锁',i)
    
        lock.acquire() # 加锁,此区域的代码同一时刻只能有一个线程执行
        global n
        print('当前线程',i,'读取到的n值为:',n)
        n = i
        time.sleep(1)
        print('当前线程',i,'修改n值为:',n)
        lock.release() # 释放锁
    
    
    for i in range(10):
        t = threading.Thread(target=task,args=(i,))
        t.start()

    5、区别

    Python多线程情况下:
        - 计算密集型操作:效率低。(GIL锁)
        - IO操作: 效率高 
                        
    Python多进程的情况下:
        - 计算密集型操作:效率高(浪费资源)。 不得已而为之。
        - IO操作: 效率高 (浪费资源)。
                    
    以后写Python时:
        IO密集型用多线程: 文件/输入输出/socket网络通信
        计算密集型用多进程。
                    
                    
    扩展:
        Java多线程情况下:
            - 计算密集型操作:效率高。
            - IO操作: 效率高 
        Python多进程的情况下:
            - 计算密集型操作:效率高(浪费资源)。
            - IO操作: 效率高 浪费资源)。
                    
    Python中线程和进程(GIL锁)
        GIL锁,全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。
            
        扩展:默认GIL锁在执行100个cpu指令(过期时间)。
                        
  • 相关阅读:
    jQuery1.3.2 源码学习 2 两个重要的正则表达式
    学习 jQuery 4 使用方法选择
    学习 jQuery 6 在 TreeView 中实现全选
    jQuery1.3.2 源码学习4 init 函数分析 2
    学习 jQuery 3 选择器
    学习 jQuery 5 筛选和过滤器
    条款9:在删除选项中仔细选择
    优化3D图形流水线
    指针相减
    浅谈水体的实现
  • 原文地址:https://www.cnblogs.com/P-Z-W/p/11198073.html
Copyright © 2011-2022 走看看