zoukankan      html  css  js  c++  java
  • python--进程/线程

    进程/线程

    1 进程

    操作系统进程切换:

    1 出现IO操作:

    2 固定时间:

    2 进程定义 (资源管理单位)---(容器)

    进程就是一个程序在一个数据集上的一次动态执行过程,进程一般由程序、数据集、进程控制块三部分组成。

    实现并发过程

    进程是相互独立的。

    3 线程(最小执行单位)

    线程的出现是为了降低上下文切换的消耗,提供系统的并发性,并突破一个进程只能干一样的缺陷,使到进程内并发成为可能。

    4 进程与线程的关系

    进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配

    和调度的基本单位,是操作系统结构的基础

    线程则是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位

    进程与线程的关系:

    (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

    (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源

    (3)CPU分给线程,即真正在CPU上运行的是线程

    5 并行和并发

    并行处理(Parallel Processing)

    是计算机系统中能同时执行两个或更多个处理的一种计算方法。并行处理可同时工作与统一程序的不同方面。并行处理的主要目的是节省大型和复杂问题的解决时间

    并发处理(concurrency Processing)

    指一个时间段中有几个程序处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机(CPU)上运行

    并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力,所以说,并行是并发的子集

    注意:

    Python败笔多线程:由于GIL,导致同一时刻,同一进程只能有一个线程被运行。多进程可以并行,多线程不能并行。

    6 同步与异步

    同步:在计算机领域,同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去

    异步:是指进程不需要一直等待下去,而是继续执行面的操作,不管其他进程的状态,当有消息返回时系统会通知进程进行处理

    7 Threading模块

     Thread类执行创建:

    import threading
    import time
    
    def listen():
        print("listen to the music")
        time.sleep(3)
        print("listne stop")
    
    def write():
        print("writing blog")
        time.sleep(5)
        print("writing stop")
    
    t1=threading.Thread(target=listen) #生成一条线程
    t2=threading.Thread(target=write) #生成第二条线程
    t1.start() #启动线程
    t2.start()
    print("ending") #主线程
    
    
    
    执行效果:
    listen to the music
    writing blog
    ending
    listne stop
    writing stop
    

    Thread类继承式创建:

    import threading
    import time
    class Mythread(threading.Thread):
        def __init__(self,num):
            threading.Thread.__init__(self)
            self.num=num
        def run(self):
            print("running on number:%s"%self.num)
            time.sleep(3)
    t1=Mythread(56)
    t2=Mythread(73)
    t1.start()
    t2.start()
    print("ending")
    
    
    
    执行结果:
    running on number:56
    running on number:73
    ending
    

      

    Thread类的实例方法:  

     Join()

    t.join() : 线程对象t未执行完,会阻塞你的主线程。跟子线程没有关系

    import threading
    import time
    from time import ctime,sleep
    
    def Music(name):
        print("Begin listening to {name}".format(name=name,time=ctime()))
        sleep(3)
        print("end listenting{time}".format(time=ctime()))
    def Blog(title):
        print("Begin recording the {title}".format(title=title,time=ctime ()))
        sleep(5)
        print("end recording the {time}".format(time=ctime()))
    threads=[]
    t1=threading.Thread(target=Music,args=("FILL ME",))
    t2=threading.Thread(target=Blog,args=("python",))
    
    threads.append(t1)
    threads.append(t2)
    if __name__ == '__main__':
        for t in threads:
            t.start()
            # t.join() # 最后出现主程序 等t1  t2执行完之后
        # t1.join()  #t1线程不结束 其他线程不能执行 先执行t1,t2 然后在执行t1结束之后再执行主线程
        t2.join() #t1 t2执行完之后再打印主程序
    
        print("all over %s" %ctime())
    

    setDeamon(True)  

           将线程声明为守护线程,必须在start()方法调用之前设置,如果不设置为守护线程程序会被无限挂起。

           当我们在程序运行中,执行一个主线程,如果主线程有创建一个子线程 就兵分两路,分别运行,那么当主线程完成

           想退出时,会检验子线程是否完成,如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是只要主线程

           完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以用setDeamon方法啦

    import threading
    import time
    from time import ctime,sleep
    
    def Music(name):
        print("Begin listening to {name}".format(name=name,time=ctime()))
        sleep(3)
        print("end listenting{time}".format(time=ctime()))
    def Blog(title):
        print("Begin recording the {title}".format(title=title,time=ctime ()))
        sleep(5)
        print("end recording the {time}".format(time=ctime()))
    threads=[]
    t1=threading.Thread(target=Music,args=("FILL ME",))
    t2=threading.Thread(target=Blog,args=("python",))
    
    threads.append(t1)
    threads.append(t2)
    if __name__ == '__main__':
        # 守护线程跟着主线程走,t1 t2两个都设置为守护线程,主线程执行完 其他就都不执行
        # t1.setDaemon(True)  #把t1设置为守护线程,等待t2执行结束,但是t1也需要执行,正常执行
        t2.setDaemon(True) #把t2设置为守护线程,主线程结束,t2也就跟着结束,不执行
        for t in threads: #for遍历
            t.start()
      
        print("all over %s" %ctime())
    

    其他方法:

     Thread实例对象的方法

     isAlive():返回线程是否活动的

     getName():返回线程名

     setName():设置线程名

     

    threading模块提供的一些方法:

     threading.currentThread(): 返回当前的线程变量。

     threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

     threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

    8 GIL(全局解释锁)

    Python中的线程是操作系统的原生线程,python虚拟机使用一个全局解释器锁(Global Interpreter Lock)来互斥线程对python虚拟机的使用。为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,所有引入了GIL。

    加在C python解释其上,为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,所以引入了GIL。

    GIL:在一个线程拥有了解释器的访问权之后,其他的所有线程都必须等他它释放解释器的访问权,即使这些线程的下一条指令并不会互相影响。

    在调用任何Python  C  API之前,要先获得GIL

    GIL缺点:多处理器退化为单处理器;优先:避免大量的加解锁操作

    GIL的影响

    无论你启多个线程,你有多少个cpu,Python在执行一个进程的时候会谈定的在同一时刻只允许一个线程运行。

    所有,python是无法利用多核CPU实现多线程的

    这样,python对于计算机密型的任务开多线程的效率甚至不如串行(没有大量切换),但是,对于IO密集型的任务效率还是有显著提升的。

    import time
    
    def cal(n):
        sum=0
        for i in range(n):
            sum+=i
    
    s=time.time()
    
    # import threading
    # t1=threading.Thread(target=cal,args=(10000000,))
    # t2=threading.Thread(target=cal,args=(10000000,))
    #
    # t1.start()
    # t2.start()
    # t1.join()
    # t2.join()
    # # time 10.940000057220459
    # # time 1.1090002059936523
    
    cal(10000000)
    cal(10000000)
    
    print("time",time.time()-s)
    # time 10.986999750137329
    # time 1.128000020980835
    

    计算密集型:一直在使用CPU

    IO:存在大量IO操作

    总结:对于计算密集型任务:Python的多线程并没有用

            对于IO密集型任务:Python的多线程是有意义的

    Python使用多核:开进程,弊端:开销大而且切换复杂

  • 相关阅读:
    数字签名与HTTPS详解
    利用策略模式优化过多 if else 代码
    Redis 的事务到底是不是原子性的
    Spring Boot项目的接口防刷
    深入分析 ThreadLocal
    什么是四层和七层负载均衡?他们之间的区别是什么?
    MyEclipse或Eclipse中project的导入和导出
    org.hibernate.exception.ConstraintViolationException: could not insert:
    C++ STL vector(向量容器)的使用(附完整程序代码)
    Swift2.0语言教程之函数嵌套调用形式
  • 原文地址:https://www.cnblogs.com/niejinmei/p/6827074.html
Copyright © 2011-2022 走看看