# -*- coding:utf-8 -*-
# Create by 27
# @Time : 2020/2/27 17:38
import time

__author__ = '27'
'''
计算机资源是稀缺的，需要竞争
每个应用至少有一个进程
进程是竞争计算机资源的基本单位

cpu，进程间切换，算法来管理
进程/线程切换时开销很大，比较浪费时间

线程是进程的一部分，一个进程可以有若干个线程。

线程产生的原因在于，cpu越来越快，用进程来管理cpu资源粒度太大了，不能够充分和有效利用cpu的高性能。
所以我们需要一个更小的单元来管理cpu的资源，进程上下文的切换是非常消耗资源的，换句话说，进程切换非常笨重，
所以我们要引入一个更加灵活轻量的机制来协调cpu资源的利用，这就是线程。
也意味着，线程之间的切换消耗的资源是比进程小很多的。

减少上下文切换的目的是让cpu资源利用的更充分来运行程序，而不是消耗在切换保存线程状态上。

！！！分工不同！！！
进程：分配CPU资源 内存资源
线程：利用cpu来执行代码的

代码->指令->cpu执行->使用资源
但是线程可以访问资源，线程属于进程，所以可以访问进程的资源
这里也可以说明，线程因为轻量，不管理资源，也不拥有资源，它是使用进程相关资源的，这就让线程切换更加快速一些，
所以线程间切换所消耗要比进程切换少很多。
'''

import threading


def worker(param):
    print("i am a new thread!!!")
    n_t = threading.current_thread()
    time.sleep(5)
    print(param)
    print("my name is {}".format(n_t.getName()))

new_t1 = threading.Thread(target=worker, name="t-1234", args=("123",))
'''
函数名称千万不能加括号，否则实例化的时候直接运行了，那这样这个函数就不是在这个线程里运行了
而是在实例化的环境所在的线程运行，这问题很严重。
'''
new_t1.start()

t = threading.current_thread()
print(t.getName())

new_t2 = threading.Thread(target=worker, name="t-9999", kwargs={"param": "0099"})
new_t2.start()

# 线程的好处：更加充分的利用CPU的性能优势
# 多线程是异步编程的一种形态
# 对于一个单核CPU，同一时间只允许一个线程来使用CPU执行相关代码，那这样的话多线程的意义在于？
'''
这是建立在单核的情况，但是多核呢？多核CPU完全有能力让不同的核处理不同的线程，这时就是在并行的执行程序。
'''

'''
python不能充分利用多核的CPU的优势！！！！！！
原因就在于python的GIL，global interpreter Lock，不管你计算机有多少个核，也不管你开了多少个线程，
它会使python代码在同一时刻只能在一个核上执行一个线程。

锁 ：存在的目的是为了线程安全

线程访问的是进程的资源，一个进程有多个线程，所以多个线程将共享一个进程的资源，
既然有共享，那么就有可能造成资源是线程不安全的。

什么是线程不安全：
比如：
主线程：a = 3
线程1：
a += 1
print(a)
线程2：
a += 1
print(a)
这个结果是不可预知的，因为python的线程调度是python自己的解释器完成的，何时切换是不可预知的，所以整体的顺序是不一定的。

锁：
细粒度的锁：简单理解是程序员自己在代码上主动加的锁
粗粒度的锁：解释器层面加了锁->GIL，所以不管电脑的硬件条件，python解释器决定了python代码是单核单线程执行的。
python利用GIL，一定程度上保证了线程安全
代码被翻译成字节码，bytecode，一句pythoncode可能会被翻译成多行的bytecode，可以用dis来看字节码
而解释器锁是字节码的级别，可能在某一行挂起，执行别的字节码，或者是时间片轮转来执行不同代码段的字节码，所以不是绝对安全的。

python实质靠着解释器来解释代码，cpyhton解释器才有GIL，jpython是没有GIL的。
所以站在线程的角度考虑cpython是没办法很好利用cpu多核的优势的，
但是可以利用多进程机制，但是进程也有自己问题，比如资源独立，访问别的进程资源需要通过进程通信，技术复杂，并且进程切换开销太大。
'''

'''
严重依赖cpu计算的程序，被称为CPU密集型程序，比如数学计算。
但是大多数程序员编写的代码，被称为IO密集型程序
如查询数据库，请求网络资源，文件读写，web应用的瓶颈一般都是在查询数据库。

评判cpu密集型和IO密集型：是依据这段代码大部分时间花在什么类型的操作上来决定的。

python的多线程在IO密集型程序里还是有意义的，因为IO密集型的程序主要时间都花在等待，
比如数据库返回结果，网络接口请求返回结果，所以这时候它并不需要cpu参与计算，故而
在这种等待的时间，与其让单线程占用CPU，不如把线程等待的时间腾出来，换到别的线程里面，
让别的线程来使用CPU，这就是多线程在IO密集型程序里的优势。

而且我们写的大多数程序都是IO密集型的程序，所以python的多线程还是有意义的。

比如node.js也是非常适合IO密集型的程序。

但是python并不适合CPU密集型程序，因为CPU密集型程序基本上每时每刻都要CPU参与计算，
基本不会有等待时间。



'''
