python中start和run方法的区别
结论:启动线程,如果对target进行赋值,并且没有重写run方法,则线程start的时候会直接调用target中对应的方法
具体代码如下:
1、初始化一个线程
threading.Thread.__init__(self,target=thread_run()) def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): assert group is None, "group argument must be None for now" if kwargs is None: kwargs = {} self._target = target self._name = str(name or _newname()) self._args = args self._kwargs = kwargs
2、调用start启动线程
最终调用_start_new_thread方法,self._bootstrap作为传参
thread1.start() def start(self): if not self._initialized: raise RuntimeError("thread.__init__() not called") if self._started.is_set(): raise RuntimeError("threads can only be started once") with _active_limbo_lock: _limbo[self] = self try: _start_new_thread(self._bootstrap, ()) except Exception: with _active_limbo_lock: del _limbo[self] raise self._started.wait()
3、_start_new_thread等同于启动一个新线程,并在新线程中调用回调函数
_start_new_thread = _thread.start_new_thread def start_new_thread(function: Callable[..., Any], args: tuple[Any, ...], kwargs: dict[str, Any] = ...) -> int: ...
4、执行的回调函数就是上文传入的self._bootstrap, _bootstrap方法直接调用_bootstrap_inner(),而bootstrap_inner则调用run方法
def _bootstrap_inner(self): try: self._set_ident() self._set_tstate_lock() if _HAVE_THREAD_NATIVE_ID: self._set_native_id() self._started.set() with _active_limbo_lock: _active[self._ident] = self del _limbo[self] if _trace_hook: _sys.settrace(_trace_hook) if _profile_hook: _sys.setprofile(_profile_hook) try: self.run()
5、最终调用run方法
def run(self): try: if self._target: self._target(*self._args, **self._kwargs) finally: # Avoid a refcycle if the thread is running a function with # an argument that has a member that points to the thread. del self._target, self._args, self._kwargs
结论:
如果run方法被重写,则直接调用重写的run方法
如果run方法没有被重写,并且target被定义,则会直接调用线程创建时候的target方法,否则什么也不做
此处遇到一问题:
指定target参数,在执行过程中,打印的进程名mainthread(主进程),而不是之前所赋的进程名
threading.Thread.init(self,target=thread_run())
分析后发现赋予target的是执行的函数体,因此会先执行thread_run函数,执行结束后,将thread_run的返回值赋给了target,因为thread_run没有返回值,因此target的值是None,如果此时没有重写run函数,那么线程什么都不会做。 thread_run的执行是在主线程,而不是我们所认为的在子线程中执行thread_run
def thread_run(): print ("overwrite: 开始线程:" + threading.current_thread().name) time.sleep(2) print ("overwrite: 退出线程:" + threading.current_thread().name) class myThread (threading.Thread): def __init__(self, threadID, name, delay): threading.Thread.__init__(self,target=thread_run()) self.threadID = threadID self.name = name self.delay = delay thread1.start() thread1.join() print ("退出主线程")
运行结果:
overwrite: 开始线程:MainThread
overwrite: 退出线程:MainThread
退出主线程
到此这篇关于python中start和run方法的区别的文章就介绍到这了,更多相关python start和run方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
基于Django框架的rest_framework的身份验证和权限解析
Django 是一个基于 Python 的 Web 框架,可让您快速创建高效的 Web 应用程序,这篇文章主要介绍了基于Django框架的rest_framework的身份验证和权限解析,需要的朋友可以参考下2023-05-05封装 Python 时间处理库创建自己的TimeUtil类示例
这篇文章主要为大家介绍了封装 Python 时间处理库创建自己的TimeUtil类示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪2023-05-05
最新评论