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方法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!