python中start和run方法的區(qū)別
結(jié)論:啟動線程,如果對target進(jìn)行賦值,并且沒有重寫run方法,則線程start的時候會直接調(diào)用target中對應(yīng)的方法
具體代碼如下:
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、調(diào)用start啟動線程
最終調(diào)用_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等同于啟動一個新線程,并在新線程中調(diào)用回調(diào)函數(shù)
_start_new_thread = _thread.start_new_thread def start_new_thread(function: Callable[..., Any], args: tuple[Any, ...], kwargs: dict[str, Any] = ...) -> int: ...
4、執(zhí)行的回調(diào)函數(shù)就是上文傳入的self._bootstrap, _bootstrap方法直接調(diào)用_bootstrap_inner(),而bootstrap_inner則調(diào)用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、最終調(diào)用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
結(jié)論:
如果run方法被重寫,則直接調(diào)用重寫的run方法
如果run方法沒有被重寫,并且target被定義,則會直接調(diào)用線程創(chuàng)建時候的target方法,否則什么也不做
此處遇到一問題:
指定target參數(shù),在執(zhí)行過程中,打印的進(jìn)程名mainthread(主進(jìn)程),而不是之前所賦的進(jìn)程名
threading.Thread.init(self,target=thread_run())
分析后發(fā)現(xiàn)賦予target的是執(zhí)行的函數(shù)體,因此會先執(zhí)行thread_run函數(shù),執(zhí)行結(jié)束后,將thread_run的返回值賦給了target,因為thread_run沒有返回值,因此target的值是None,如果此時沒有重寫run函數(shù),那么線程什么都不會做。 thread_run的執(zhí)行是在主線程,而不是我們所認(rèn)為的在子線程中執(zhí)行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 ("退出主線程")
運行結(jié)果:
overwrite: 開始線程:MainThread
overwrite: 退出線程:MainThread
退出主線程
到此這篇關(guān)于python中start和run方法的區(qū)別的文章就介紹到這了,更多相關(guān)python start和run方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Python圖像處理庫Pillow處理圖像文件的案例分析
本文將通過使用Python圖像處理庫Pillow,幫助大家進(jìn)一步了解Python的基本概念:模塊、對象、方法和函數(shù)的使用,文中代碼講解的非常詳細(xì),需要的朋友可以參考下2023-07-07
git使用.gitignore設(shè)置不生效或不起作用問題的解決方法
下面小編就為大家?guī)硪黄猤it使用.gitignore設(shè)置不生效或不起作用問題的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
使用scrapy ImagesPipeline爬取圖片資源的示例代碼
這篇文章主要介紹了使用scrapy ImagesPipeline爬取圖片資源的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
python 監(jiān)測內(nèi)存和cpu的使用率實例
今天小編就為大家分享一篇python 監(jiān)測內(nèi)存和cpu的使用率實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11

