• 操作系统/应用程序, 操作中的"并发", 其他语言线程、进程, Python中线程和进程(GIL锁:全局解释器锁), Python线程编写+锁


    一. 操作系统/应用程序

        a. 硬件
            - 硬盘
            - CPU
            - 主板
            - 显卡
            - 内存
            - 电源
            ...
        b. 装系统(软件)
            - 系统就是一个由程序员写出来软件,该软件用于控制计算机的硬件,让他们之间进行相互配合。

        c. 安软件(安装应用程序)
            - QQ
            - 百度云
            - pycharm
            ...

    二. 并发和并行
        并发,伪,由于执行速度特别快,人感觉不到停顿。
        并行,真,创建10个人同时操作。

    三. 线程、进程
        a. 单进程、单线程的应用程序

            print('666')

        b. 什么是线程?什么是进程?
            Python自己没有这玩意,Python中调用的操作系统的线程和进程。

        c. 单进程、多线程的应用程序
            代码:

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

     一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以创建多个线程(默认一个)。

        总结:

            1. 操作系统帮助开发者操作硬件。
            2. 程序员写好代码在操作系统上运行(依赖解释器)。

    Python多线程情况下:
        - 计算密集型操作:效率低。(GIL锁)
        - IO操作: 效率高

    Python多进程的情况下:
        - 计算密集型操作:效率高(浪费资源)。 不得已而为之。
        - IO操作: 效率高 (浪费资源)。

    写Python时:
        IO密集型用多线程: 文件/输入输出/socket网络通信
        计算密集型用多进程。

    扩展:
        Java多线程情况下:
            - 计算密集型操作:效率高。
            - IO操作: 效率高
        Python多进程的情况下:
            - 计算密集型操作:效率高(浪费资源)。
            - IO操作: 效率高 浪费资源)。

    四. Python中线程和进程(GIL锁)
        GIL锁,全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。

        默认GIL锁在执行100个cpu指令(过期时间)。# v = sys.getcheckinterval()


    五. Python线程编写

    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()
    
    ###################### 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()
    
    # ################# 锁 ###################
    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()
    

    为什么要创建线程?
        由于线程是cpu工作的最小单元,创建线程可以利用多核优势实现并行操作(Java/C#)。
        线程是为了工作。
        
    为什么要创建进程?
        进程和进程之间做数据隔离(Java/C#)。
        进程是为了提供环境让线程工作。

    Python
        多线程无法利用多核优势。
        开多进程处理(浪费资源)
        IO密集型:多线程
        计算密集型:多进程

  • 相关阅读:
    数据库中分组函数rank() ntile() dense_rank() row_number
    seo关键指令
    asp.net中的几个路径问题!
    Jquery 1.6+新属性prop()使用
    SEO
    电脑屏幕显示米黄色!
    C#中对类的扩展
    使用bat文件发布asp.net程序
    SEO优化
    当打开一个网页,浏览器host服务器做了啥?
  • 原文地址:https://www.cnblogs.com/NachoLau/p/9622177.html
Copyright © 2020-2023  润新知