前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python关于threading.Thread的一顶点儿零散笔记

python关于threading.Thread的一顶点儿零散笔记

作者头像
qsjs
发布2021-07-27 12:00:35
5660
发布2021-07-27 12:00:35
举报
A.

类的初始化函数__init__, 其传递的参数一般采用"具体参数, 可变长元组参数args,可变长字典类型参数 kwargs "相互配合的方式,比如threading.Thread 的初始化函数:

代码语言:javascript
复制
def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):        
#其中 kwargs=None, 也可以写作 kwargs={}, 注意args, kwargs 需要以关键字参数的形式进行传递.

采用上述写法的好处是: 明确指定了有名称的参数(比如上例的group, target,name, daemon),同时可以接受传入的额外参数(args,kwargs 来接受). 这样,就保证了可以接受所有的参数. 如果是自己定义的class, 也可以采用这种方式进行参数传递,确保class 在实例化的时候,可以接受所有的参数.在上述的例子中,所有参数都是可选参数,而如果要传递位置参数,那么明确指出就可以了.

B.

在没有指定父类的情况下,所有类的父类默认就是object, 通常是忽略不写的. 但是如果明确指定了当前类的父类,那么关于当前类的初始化函数的参数传递规则如下: 1). 如果当前类在父类的基础上需要增加新的参数,那么直接在初始化函数__init__的参数列表中新增对应的参数就可以了,比如在上述threading.Thread 类的基础上,创建自定义的class,那么这个自定义的类可以这么写:

代码语言:javascript
复制
class mythread(threading.Thread):          #指定父类
       def __init__(self,group=None, target=None, name=None, args=(), kwargs=None, daemon=None, mypara=None)          
#在父类的基础上,初始化的时候增加了新的参数: mypara,所以简单在后面的参数列表追加就可以了
              super(mythread,self).__init__(*args,**kwargs)
              self.newpara=mypara    

2). 如果当前类不需要新增传递的参数,那么在当前类的初始化的时候,直接采用(*args,**kwargs)来接受所有参数,就更简单省事. 而有新增加的参数的时候,才使用上面描述的方式. 3). 为了确保能够继承父类的方法和属性,那么一般在当前类的初始化函数中,会首先通过super方法来调用父类的初始化函数. 比如上例的super 方法的使用,然后再执行当前类初始化时候要做的特定的action, 当然如果不调用父类的初始化函数也是可以的,这样就无法使用父类的方法以及属性了. 这其实是类的继承的一个特点.

C.

关于在class的方法里面调用 class外的函数,这时候向class传递的参数是一个函数,那么直接写函数的名称,不要把函数的名称写成字符串,这样在 class的方法中就可以使用如下的方式调用这个函数,这也是在class的方法中调用 class 之外的方法的典型用法:

代码语言:javascript
复制
class Thread:
       ...    #省略源代码中的一部分... 
       def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None):          #初始化函数...
       ...    #省略源代码中的一部分... 
             self._target = target          #target其实就是线程所执行的函数的名称
             self._args = args              #线程执行的函数的元组参数
             self._kwargs = kwargs     #线程执行的函数的字典参数
      ...    #省略源代码中的一部分... 
      def run(self):
            ...
            self._target(*self._args, **self._kwargs)        #函数调用以及参数传递
           ...
D.

threading.Thread 这个类没有包括线程结束的方法,这个原因是:贸然结束线程可能导致多种预测不到的问题,比如线程结束了,但是其 加锁的资源并没有释放,或者其处理的数据还没有更新到磁盘等... 而如果要结束线程,网络上主要有两种方式: 1). 用 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,SystemExit)进行强制结束. 可能带来上述的不良后果.而为了解决强制结束带来的问题,可以在强制结束之前调用 对应的 线程清理函数,首先执行相应的清理操作,然后再强制结束线程的运行. 还有一个弊端就是,如果不是通过Python解释器进行的调用,那么因为上述命令是通过触发异常来结束线程的运行,所以就无法捕获到异常,也就无法终止线程的运行了,如果是纯python编程,那么应该没有这个问题. 该方法的好处是:可以随时结束线程的运行,无论线程本身是否循环执行都可以结束. 2). 在threading这个模块中,还有一个class 叫做Event,该Event 类拥有is_Set 以及set, clear 等方法,可以用于设置标志位,所以可以在线程中通过不停检测这个标志位从而实现线程的自杀,从而结束线程的运行;该方法有一个弊端: 如果线程函数并不是循环执行,那么如何来检测这个标志位呢? 而如果线程本身就是不断循环,那么采用这种方式相对更好. 属于线程自杀结束执行.

原创笔记,转载请注明出处.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • A.
  • B.
  • C.
  • D.
  • 原创笔记,转载请注明出处.
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档