日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

孤荷凌寒自学python第三十八天初识python的线程控制

發布時間:2025/5/22 python 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 孤荷凌寒自学python第三十八天初识python的线程控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
孤荷凌寒自學python第三十八天初識python的線程控制

?

(完整學習過程屏幕記錄視頻地址在文末,手寫筆記在文末)

一、線程

在操作系統中存在著很多的可執行的應用程序,每個應用程序啟動后,就可以看著是一個進程,當打開WINDOWS任務管理器時,在任務管理器的進程選項卡中列出的就是一個一個的進程,基本上每個應用程序都對應著至少一個進程。

在同一進程中,也許同時在做著不止一件事情,比如在向程序界面上顯示信息和接受信息的同時,程序也在和遠端服務器通信讀取數據,則這兒至少有兩個線程運行在同一個進程中。

我的簡單理解是,在同一個操作系統的進程中,可以同時執行多個線程的任務。

?

二、threading模塊

threading模塊是Python?中主要的線程控制模塊。

使用threading模塊前必須先聲明引用:

import threading

?

三、threading模塊的常見子類與屬性和方法

1

threading.activeCount()

執行此方法返回當前進程下所有活動的線程總數。

?

2

threading.enumerate()

此方法直接返回一個 迭代器,迭代器中包含了,所有當前進程下的所有線程的信息。

在實際測試中,發現在循環打印時,總是不打印出第0個線程的信息,沒有核準原因。

見后面的測試代碼與結果。

?

3

threading.Thread

這是threading模塊下的子模塊(類),特別注意Thread模塊的首字母是大寫的。這是最容易疏忽之處。

?

四、獲取或定義得到一個threading.Thread線程對象

可以通過以下方式得到threading.Thread線程對象

1.第一種:

thread對象=threading.Thread(target=要讓新線程執行的函數名?, args=這個函數需要的參數組成的元組)

測試代碼:

def?f1(n):

??? strtime=str(datetime.now())

????print('線程'?+ n +?'正在運行中....線程啟動于:'?+strtime)

?

t=threading.Thread(target=f1,args=('t1',))

上面代碼中,我創建了一個線程對象?t ,這個線程如果啟動,將執行函數f1定義好的內部代碼塊。

Thread類的建構代碼(初始化函數)中,要求傳遞的兩個實參,只能按【關鍵字參數】形式傳遞進去。

?

2.第二種

thread對象=threading.Thread(target=要調用的作為函數用的類名(此類的初始化方法需要的參數列表))

測試代碼:

class?myt(object):

?

????def?__init__(self,n):

????????self.n=n

?

????def?__call__(self):

??????? strtime=str(datetime.now())

????????print('線程'?+?self.n +?'正在運行中....線程啟動于:'?+strtime)

?

t=threading.Thread(target=myt('t1'))

這種方式中,線程t啟動后,將執行的是一個可以當著函數來調用的類myt.

myt是一個可以被 當著函數來使用的類,因為在類的內部代碼塊中定義有:__call__()私有方法。

與第一種方式不同的地方在于,這次只向Thread初始化方法傳遞了一個關鍵字實參target。

?

3.第三種方式

直接寫一個新的繼承自threading.Thread類的子類,然后,用新的類來初始化得到一個thread對象。

測試代碼:

class?myt(threading.Thread):

?

????def?__init__(self,n):

??????? threading.Thread.__init__(self)

????????self.n=n

?

????def?run(self):

??????? strtime=str(datetime.now())

????????print('線程'?+?self.n +?'正在運行中....線程啟動于:'?+strtime)

?

t=myt('t1')

首先建構了一個繼自threading.Thread的類?myt,這個類的特點有:

(1)在子類的__init__()方法中,必須 先調用父類的__init__()方法,在我的上機測試過程中(見過程屏幕錄像,這兒反復出錯,結果發現就是沒有先調用父類的__init()__方法,引發的錯誤。

而原因在測試當時沒有思考出來,所以大家在我的測試屏幕錄像中可以看到沒有想明白,現在思考下,發現可能是因為在threading.Thread類本身的__init__()中要執行非常重要的初始化操作,才能保證thread本類實例化后的對象功能可用,我找到了threading.Thread類本身的__init__()方法的代碼如下:

?

????def?__init__(self,?group=None,?target=None,?name=None,

?????????????????args=(),?kwargs=None, *,?daemon=None):

????????"""Thisconstructor should always be called with keyword arguments. Arguments are:

?

??????? *group* should be None; reserved forfuture extension when a ThreadGroup

??????? class is implemented.

?

??????? *target* is the callable object to beinvoked by the run()

??????? method. Defaults to None, meaningnothing is called.

?

??????? *name* is the thread name. By default,a unique name is constructed of

??????? the form "Thread-N" where Nis a small decimal number.

?

??????? *args* is the argument tuple for thetarget invocation. Defaults to ().

?

??????? *kwargs* is a dictionary of keywordarguments for the target

??????? invocation. Defaults to {}.

?

??????? If a subclass overrides theconstructor, it must make sure to invoke

??????? the base class constructor (Thread.__init__())before doing anything

??????? else to the thread.

?

??????? """

????????assert?group?is?None,?"groupargument 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

????????if?daemon?is?not?None:

????????????self._daemonic= daemon

????????else:

????????????self._daemonic= current_thread().daemon

????????self._ident=?None

????????self._tstate_lock=?None

????????self._started= Event()

????????self._is_stopped=?False

????????self._initialized=?True

????????# sys.stderr is notstored in the class like

????????# sys.exc_infosince it can be changed between instances

????????self._stderr= _sys.stderr

????????# For debugging and_after_fork()

??????? _dangling.add(self)

?

以上代碼可以證明我的猜測是正確的,因此在測試屏幕錄像中我沒有想通的問題現在基本上有答案了,當然正確與否希望大家批評指正。

(2)在定義繼承自threading.Thread類的子類中,__call__()方法 需要被 改名為?run()方法。

?

五、threading.Thread對象的主要屬性與方法有:

1 name屬性

此屬性可讀寫,用以設置和獲取線程對象的名稱。

?

2 getName()方法

用于獲取線程對象的名稱。

?

3 setName()方法

用于設置線程對象的名稱。

?

4 ident

此屬性是只讀的,獲取線程對象的標識碼,標識碼是數字。

?

5 is_alive()??isAlive()

這兩個方法用于判斷線程對象是否正在運行(存活),返回布爾對象。

?

6 join()

這是線程對象非常 重要 的方法,此方法有一個可選 形參?timeout

執行線程的此方法后,會將調用 此線程的上級線程 阻塞,然后等待此線程執行完成,如果為join()方法設置了timeout時間,那么從此線程開始執行起計時,達到timeout指定的時間限額時,將自動解除對上級線程的阻塞。

在今天 的測試過程中,沒有著重測試此方法的具體功用,理解可能不完全準確。

?

7 start()

線程執行此方法后,線程就開始執行指定任務,同時線程的isAlive標識將顯示為True

此外,我沒有發現線程有stop()方法,目前也沒有研究到中止指定線程執行的其它方法。

?

測試代碼一 :

importthreading

from?datetimeimport?datetime

?

intcount=3

?

class?myt(object):

?

????def?__init__(self,n):

????????self.n=n

?

????def?__call__(self):

??????? strtime=str(datetime.now())

????????print('線程'?+?self.n +?'正在運行中....線程啟動于:'?+strtime)

?

def?main():

??? threads=[]

??? x=range(intcount)

????for?n?in?x:

??????? t=threading.Thread(target=myt('t'?+?str(n)))

????????#if n==1:

????????#??? t.setDaemon(True)

??????? t.name='t'?+?str(n)

??????? threads.append(t)

?

????for?n?in?x:

??????? threads[n].start()

?

????#print(threading.activeCount())

????for?item?inthreading.enumerate():

????????print(item)

?

????print('--------')

?

????for?item?inthreads:

????????print(item)

?

????print(threads[0].isAlive())

?

????for?n?in?x:

??????? threads[n].join()

?

if?__name__=='__main__':

??? main()

執行結果:

線程t0正在運行中....線程啟動于:2018-08-1617:31:08.939618

線程t1正在運行中....線程啟動于:2018-08-1617:31:08.939618

線程t2正在運行中....線程啟動于:2018-08-1617:31:08.940647

<_MainThread(MainThread, started 4436)>

?

<Thread(t1, stopped 2444)>

<Thread(t2, stopped 8676)>

--------

<Thread(t0, stopped 3188)>

<Thread(t1, stopped 2444)>

<Thread(t2, stopped 8676)>

False

測試代碼二:

importthreading

fromdatetime?import?datetime

?

intcount=3

?

class?myt(threading.Thread):

?

????def?__init__(self,n):

??????? threading.Thread.__init__(self)

????????self.n=n

?

????def?run(self):

??????? strtime=str(datetime.now())

????????print('線程'?+?self.n +?'正在運行中....線程啟動于:'?+strtime)

?

def?main():

??? threads=[]

??? x=range(intcount)

????for?n?in?x:

??????? t=myt('t'?+?str(n))

????????#if n==1:

????????#??? t.setDaemon(True)

??????? t.name='t'?+?str(n)

??????? threads.append(t)

?

????for?n?in?x:

??????? threads[n].start()

?

????#print(threading.activeCount())

????for?item?inthreading.enumerate():

????????print(item)

?

????print('--------')

?

????for?item?inthreads:

????????print(item)

?

????print(threads[0].isAlive())

?

????for?n?in?x:

??????? threads[n].join()

?

if?__name__=='__main__':

??? main()

執行結果:

線程t0正在運行中....線程啟動于:2018-08-1617:32:36.893226

線程t1正在運行中....線程啟動于:2018-08-1617:32:36.894223

線程t2正在運行中....線程啟動于:2018-08-1617:32:36.895221

<_MainThread(MainThread, started 8884)>

?

<myt(t2, stopped 8940)>

--------

<myt(t0, stopped 7152)>

<myt(t1, stopped 8744)>

<myt(t2, stopped 8940)>

False

注意執行結果中,threading.enumerate()方法返回的迭代器在循環取出對象時,總沒有完整打印,且有空行。這點沒有思考出答案。搜索網絡沒有找到答案,還有待繼續思考,并懇請高手予以指點。

?

——————————

今天整理的學習筆記完成,最后例行說明下我的自學思路:

根據過去多年我自學各種編程語言的經歷,認為只有真正體驗式,解決實際問題式的學習才會有真正的效果,即讓學習實際發生。在2004年的時候我開始在一個鄉村小學自學電腦 并學習vb6編程語言,沒有學習同伴,也沒有高師在上,甚至電腦都是孤島(鄉村那時還沒有網絡),有的只是一本舊書,在痛苦的自學摸索中,我找到適應自己零基礎的學習方法:首先是每讀書的一小節就作相應的手寫筆記,第二步就是上機測試每一個筆記內容是否實現,其中會發現書中講的其實有出入或錯誤,第三步就是在上機測試之后,將筆記改為電子版,形成最終的修訂好的正確無誤的學習筆記。

通過反復嘗試錯誤,在那個沒有分享與交流的黑暗時期我摸黑學會了VB6,爾后接觸了其它語言,也曾聽過付費視頻課程,結果發現也許自己學歷果然太低,就算是零基礎的入門課程,其實也難以跟上進度,講師的教學多數出現對初學者的實際情況并不了解的情況,況且學習者的個體也存在差異呢?當然更可怕的是收費課程的價格往往是自己難以承受的。

于是我的所有編程學習都改為了自學,繼續自己的三步學習筆記法的學習之路。

當然自學的最大問題是會走那么多的彎路,沒有導師直接輸入式的教學來得直接,好在網絡給我們帶來無限搜索的機會,大家在網絡上的學習日志帶給我們共享交流的機會,而QQ群等交流平臺、網絡社區的成立,我們可以一起自學,互相批評交流,也可以獲得更有效,更自主的自學成果。

于是我以人生已過半的年齡,決定繼續我的編程自學之路,開始學習python,只希望與大家共同交流,一個人的獨行是可怕的,只有一群人的共同前進才是有希望的。

誠摯期待您的交流分享批評指點!歡迎聯系我加入從零開始的自學聯盟。

這個時代互聯網成為了一種基礎設施的存在,于是本來在孤獨學習之路上的我們變得不再孤獨,因為網絡就是一個新的客廳,我們時刻都可以進行沙龍活動。

非常樂意能與大家一起交流自己自學心得和發現,更希望大家能夠對我學習過程中的錯誤給予指點——是的,這樣我就能有許多免費的高師了——這也是分享時代,社區時代帶來的好福利,我相信大家會的,是吧!

?

根據完全共享的精神,開源互助的理念,我的個人自學錄制過程是全部按4K高清視頻錄制的,從手寫筆記到驗證手寫筆記的上機操作過程全程錄制,但因為4K高清文件太大均超過5G以上,所以無法上傳至網絡,如有需要可聯系我QQ578652607對傳,樂意分享。上傳分享到百度網盤的只是壓縮后的720P的視頻。

?

我的學習過程錄像百度盤地址分享如下:(清晰度:1280x720)

鏈接:https://pan.baidu.com/s/1n00vs2zpHiMCCf5eqykGrg?

提取碼:bgu2

?

Bilibili:

https://www.bilibili.com/video/av38088874/

?

喜馬拉雅語音筆記:

https://www.ximalaya.com/keji/19103006/144900713







轉載于:https://www.cnblogs.com/lhghroom/p/10125181.html

總結

以上是生活随笔為你收集整理的孤荷凌寒自学python第三十八天初识python的线程控制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。