• Python开发基础----多线程


    概念

    进程:进程就是一个程序在一个数据集上的一次动态执行过程

      程序:代码

      数据集:程序执行过程中需要的资源  

      进程控制块:完成状态保存的单元

    线程:线程是寄托在进程之上,为了提高系统的并发性

      线程是进程的实体

      进程是一个资源管理单元、线程是最小的执行单元

    线程和进程的关系

    (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
    (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
    (3)CPU分给线程,即真正在CPU上运行的是线程。

    进程/线程切换原则:切换的操作者,操作系统

      1、时间片,任务的处理时间

      2、遇到io操作,切换

        例如socket, accept发了一次系统调用,然后就等待操作系统调用,操作系统进行监听

      3、优先级切换

    并发:在一个时间段里,能够执行多个程序的能力

    切换:即任务状态的保存,状态的恢复,是并发的条件

      注:为了共用数据集,线程进行切换,线程切换的开销远远小于进程切换的开销

    并行:多个cpu,在同一时刻能够执行多个程序

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

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

    举个例子,打电话时就是同步通信,发短息时就是异步通信。

    python的线程

    python加锁:同一时间只有一个线程出来被执行,在一个进程下实现真正意义上的线程并行,把多核的优势给浪费了(后边会讲)

    threading模块

    Thread类直接创建

    复制代码
     1 import threading
     2 import time
     3 
     4 def countNum(n): # 定义某个线程要运行的函数
     5 
     6     print("running on number:%s" %n)
     7 
     8     time.sleep(3)
     9 
    10 if __name__ == '__main__':
    11 
    12     t1 = threading.Thread(target=countNum,args=(23,)) #生成一个线程实例
    13     t2 = threading.Thread(target=countNum,args=(34,))
    14 
    15     t1.start() #启动线程
    16     t2.start()
    17 
    18     print("ending!")
    复制代码

    Thread类继承式创建

    复制代码
    #继承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(78)
    
    t1.start()
    t2.start()
    print("ending")
    复制代码

    join()和setDaemon()

    复制代码
    # join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
    
    # setDaemon(True):
            '''
             将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。
    
             当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程 就分兵两路,分别运行,那么当主线程完成
    
             想退出时,会检验子线程是否完成。如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是只要主线程
    
             完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以 用setDaemon方法啦'''
    
    
    import threading
    from time import ctime,sleep
    import time
    
    def Music(name):
    
            print ("Begin listening to {name}. {time}".format(name=name,time=ctime()))
            sleep(3)
            print("end listening {time}".format(time=ctime()))
    
    def Blog(title):
    
            print ("Begin recording the {title}. {time}".format(title=title,time=ctime()))
            sleep(5)
            print('end recording {time}'.format(time=ctime()))
    
    
    threads = []
    
    
    t1 = threading.Thread(target=Music,args=('FILL ME',))
    t2 = threading.Thread(target=Blog,args=('',))
    
    threads.append(t1)
    threads.append(t2)
    
    if __name__ == '__main__':
    
        #t2.setDaemon(True)
    
        for t in threads:
    
            #t.setDaemon(True) #注意:一定在start之前设置
            t.start()
    
            #t.join()
    
        #t1.join()
        #t2.join()    #  考虑这三种join位置下的结果?
    
        print ("all over %s" %ctime())
    复制代码
    复制代码
    daemon
    A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.
    
    The entire Python program exits when no alive non-daemon threads are left.
    
    当daemon被设置为True时,如果主线程退出,那么子线程也将跟着退出,
    
    反之,子线程将继续运行,直到正常退出。
    复制代码

    其它方法

    复制代码
    Thread实例对象的方法
      # isAlive(): 返回线程是否活动的。
      # getName(): 返回线程名。
      # setName(): 设置线程名。
    
    threading模块提供的一些方法:
      # threading.currentThread(): 返回当前的线程变量。
      # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
      # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
    复制代码

    IO密集型任务:程序中存在大量IO操作

    计算密集型任务:程序中存在大量计算操作

    对于python而言,处理io密集型任务有优势,对于计算密集型任务没优势

  • 相关阅读:
    基于spark-streaming实时推荐系统
    xgb
    FM算法解析及Python实现
    FM算法
    计算广告
    转发推荐系统文章
    【spark】dataframe常见操作
    VS Code WSL 2 配置 Spring Boot 2
    Makefile
    Paper English
  • 原文地址:https://www.cnblogs.com/chenqizhou/p/7200929.html
Copyright © 2020-2023  润新知