• python高级编程——线程和线程池


    线程模块
              线程的特点:
                   本质上是异步的、需要多个并发活动、每个活动的处理顺序可能是不确定的、或者说是随机的,不可预测的,宏观上是同时运行的
         
              进程与线程的关系:
                   多任务可以由多进程完成,也可以由一个进程内的多线程完成,进程有若干个线程组成,一个进程至少有一个线程。在使用线程的过程中一般建议使用threading模块,相比于_thread高级一些。很多地方线程和进程是一样的
              
              threading模块的Thread类:
                   属性: name ------>名字
                             ident ------->线程标识符
                             daemon ------->守护线程的标识,类型bool
                   方法:__init__构造函数,和进程的构造函数差不多,可以参考进程的构造函数
                             start:线程启动
                             run:定义线程功能方法,一般是在子类重新定义的
                             join:在启动线程终止前一直挂起,timeout是阻塞时间
     
    使用Thread类创建线程的三种方法:(直接看实例)
              ①创建Thread类实例,传给他一个函数
    # 1、创建Thread类实例,传给它一个函数
    # 线程的属性和方法
    def task(task_id, task_time):
        print("start task", task_id, "at", ctime())
        sleep(task_time)
        print("task", task_id, "done at", ctime())
    
    
    if __name__ == "__main__":
        print("准备创建线程")
        # 创建Thread类实例,传给它一个函数,传参也是关键字参数
        t = threading.Thread(target=task, args=(1, 2))
        print("准备启动线程")
        # 两种设置守护线程的方式,
        # 守护线程和守护进程就是主进程运行完,守护进(线)程立刻结束
        # t.setDaemon(True)
        t.daemon = True
        t.start()
        # 名字以Thread-N起名,N从1开始
        print("线程的名字:", t.name)
        print("线程的id:", t.ident)
        print("线程已经启动")
      ②创建Thread的实例,传给他一个可调用的实例化对象
    # 2、创建Thread的实例,传给他一个可调用的类的实例化对象
    # 重写方法__call__
    def task(task_id, task_time):
        print("start task", task_id, "at", ctime())
        sleep(task_time)
        print("task", task_id, "done at", ctime())
    
    
    # 创建一个简单的类
    class ThreadFunc(object):
        def __init__(self, *args):
            super().__init__()
            self.args = args
    
        # __call__功能是使得实例化对象也可以调用
        def __call__(self, *args, **kwargs):
            task(*self.args)
    
    
    if __name__ == "__main__":
        t = threading.Thread(target=ThreadFunc(1, 2))
        t.start()
        t.join()

      ③派生Thread的子类,并创建子类的实例(推荐)

    # 3、派生Thread的子类,并创建子类的实例(推荐)
    def task(task_id, task_time):
        print("start task", task_id, "at", ctime())
        sleep(task_time)
        print("task", task_id, "done at", ctime())
    
    
    class MyThread(threading.Thread):
        def __init__(self, *args):
            super().__init__()
            self.args = args
    
        def run(self):
            task(*self.args)
    
    
    if __name__ == "__main__":
        myThread = MyThread(1, 2)
        # 这里不是调用run方法,和进程的使用差别不大
        myThread.start()
        myThread.join()
              线程的状态(一般是简化之后的)
                    1. 新建(NEW):新创建了一个线程对象。
                    2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用 了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调 度选中,获取cpu 的使用权 。 
                    3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片( timeslice) ,执行程序代码。
                    4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也 即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状 态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况 分三种:
            (一). 等待阻塞:sleep
            (二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线 程占用。
                   5. 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run() 方法,则该线程结束生命周期。死亡的线程不可再次复生。
     
     
                   状态图切换:

      总结:在一个进程的多个线程是可以共享进程的全局变量的,但是多个线程若同时修改这个全局变量,就可能造成多个线程之间对全局变量的混乱(即线程是不安全的)下一篇就是就要讲到锁机制了。

     
     
     
     
     
  • 相关阅读:
    Discuz!X3.1插件创建与配置
    Discuz!X3.1如何设置下载附件扣除积分
    Discuz!X3.1标签使用(二)
    Discuz!X3.1标签使用(一)
    Discuz!X3.1后台操作技巧(整合)
    Discuz!X3.1数据库的操作(三)
    Discuz!X3.1数据库的操作(二)
    Discuz!X3.1数据库的操作(一)
    Discuz!X3.2导航下拉菜单样式修改
    【discuz x3】源代码中的sql调用
  • 原文地址:https://www.cnblogs.com/aitiknowledge/p/11431399.html
Copyright © 2020-2023  润新知