<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python必學(xué)知識(shí)點(diǎn)總結(jié)

          共 9078字,需瀏覽 19分鐘

           ·

          2022-02-20 14:26

          1. txt文件讀取,考點(diǎn):分批讀取文件內(nèi)容,避免內(nèi)存不足的情況;

          ## 一次性全部讀到內(nèi)存
          def get_lines():
          with open('file.txt','rb') as f:
          return f.readlines()

          ## 分批讀到內(nèi)存,避免內(nèi)存不足;
          def get_line():
          data_list = list()
          with open('file.txt','rb') as f:
          data_item = f.readlines(60000)
          data_list.append(data_item)
          yield data_list

          if __name__ == '__main__':
          for e in get_lines():
          process(e) # 處理每一行數(shù)據(jù)

          2. 獲取文件夾下面所有文件路徑,包括多重文件夾

          import os
          ## 遞歸獲取所有文件
          def get_files_path(root_dir):
          file_path_list = list()
          for item in os.listdir(root_dir):
          item_path = os.path.join(root_dir,item)
          if os.path.isdir(item_path):
          file_path_list.extend(get_files_path(item_path))
          else:
          file_path_list.append(item_path)
          return file_path_list

          ## 非遞歸,并且只需要“.jpg“文件
          def get_file_path_list(path,file_type=".jpg"):
          data_list = list()
          for root,dirs,files in os.walk(path):
          for file in files:
          if file.endswith(file_type):
          data_list.append(os.path.join(root,file))

          return data_list

          3. 判斷這一天是這一年的第幾天

          import datetime
          def day_of_year(year:int,month:int,day:int):
          date1 = datetime.date(year=int(year),month=int(month),day=int(day))
          date2 = datetime.date(year=int(year),month=int(1),day=int(1))
          return (date1-date2).days+1

          4. 字典、列表操作

          ## 字典推導(dǎo)式
          d1 = {key:len(key) for key in ("test","python")}
          ## 字符串反轉(zhuǎn)(對(duì)key進(jìn)行反轉(zhuǎn))
          d2 = {key[::-1]:value for (key,value) in d1.items()}
          ## 字典合并
          d = dict(d1,**d2)
          ## 按key排序
          dict(sorted(d.items(), key=lambda item: item[1]))
          ## 按value排序
          dict(sorted(d.items(), key=lambda item: item[0]))
          ## 打亂list
          import random
          list1 = list(d.values()) # 返回的是一個(gè) dict_keys 對(duì)象,不再是 list 類(lèi)型,也不支持 index 索引
          random.shuffle(list1)
          ## list元素去重
          set_list = list(set(d1.values()))
          ## list元素排序
          sorted_list = sorted(list1)
          ## list元素刪除
          sorted_list.remove(sorted_list[0])
          ## list 元素過(guò)濾
          sorted_list = filter(lambda x:x>0,sorted_list)
          ## 找兩個(gè)List的相同元素
          set(d1.values())&set(d2.values())
          ## 找兩個(gè)List的不相同元素
          set(d1.keys())&set(d2.keys())
          ## 列表解析、列表推導(dǎo)式,并將字符串類(lèi)型的key值全部大寫(xiě)
          sorted_list = [item.upper() for item in list(d.keys())]

          5. python新式類(lèi)和經(jīng)典類(lèi)的區(qū)別

          a.python里凡是繼承了object的類(lèi),都是新式類(lèi);
          b....

          6. python中內(nèi)置的數(shù)據(jù)結(jié)構(gòu)有哪些

          整型int、長(zhǎng)整型long、浮點(diǎn)型float、復(fù)數(shù)complex、字符串str、
          列表list、元組tuple、字典dict、集合set
          python3中沒(méi)有l(wèi)ong,只有無(wú)限精度的int

          7. 可變類(lèi)型和不可變類(lèi)型

          1. 可變類(lèi)型有l(wèi)ist,dict;不可變類(lèi)型有string,number,tuple.
          2. 當(dāng)進(jìn)行修改操作時(shí),可變類(lèi)型傳遞的是內(nèi)存中的地址,也就是說(shuō),直接修改內(nèi)存中的值,并沒(méi)有開(kāi)辟新的內(nèi)存。
          3. 不可變類(lèi)型被改變時(shí),并沒(méi)有改變?cè)瓋?nèi)存地址中的值,而是開(kāi)辟一塊新的內(nèi)存,將原地址中的值復(fù)制過(guò)去,對(duì)這塊新開(kāi)辟的內(nèi)存中的值進(jìn)行操作。

          8. python中的super()

          Python中的super(Net, self).__init__()是指首先找到Net的父類(lèi)(比如是類(lèi)NNet),
          然后把類(lèi)Net的對(duì)象self轉(zhuǎn)換為類(lèi)NNet的對(duì)象,然后“被轉(zhuǎn)換”的類(lèi)NNet對(duì)象調(diào)用自己的init函數(shù)
          其實(shí)簡(jiǎn)單理解就是子類(lèi)把父類(lèi)的__init__()放到自己的__init__()當(dāng)中,
          這樣子類(lèi)就有了父類(lèi)的__init__()的那些東西。

          super()如果不寫(xiě)參數(shù)的話(huà),那么默認(rèn)就是super(當(dāng)前類(lèi), self)

          9. Python中類(lèi)方法、類(lèi)實(shí)例方法、靜態(tài)方法有何區(qū)別

          類(lèi)方法:是類(lèi)對(duì)象的方法,在定義時(shí)需要在上方使用@classmethod進(jìn)行裝飾,形參為cls,表示類(lèi)對(duì)象,類(lèi)對(duì)象和實(shí)例對(duì)象都可調(diào)用;
          類(lèi)實(shí)例方法:是類(lèi)實(shí)例化對(duì)象的方法,只有實(shí)例對(duì)象可以調(diào)用,形參為self,指代對(duì)象本身;
          靜態(tài)方法:是一個(gè)任意函數(shù),在其上方使用@staticmethod進(jìn)行裝飾,可以用對(duì)象直接調(diào)用,靜態(tài)方法實(shí)際上跟該類(lèi)沒(méi)有太大關(guān)系;

          10. Python單例

          import threading
          class Singleton(object):
          _instance_lock = threading.Lock() # 如果不加鎖,那么單例功能會(huì)有失效的情況。

          def __init__(self):
          pass

          def __new__(cls, *args, **kwargs):
          if not hasattr(Singleton, "_instance"): # 如果該類(lèi)“不“含有實(shí)例化對(duì)象
          with Singleton._instance_lock:
          if not hasattr(Singleton, "_instance"):
          # 用父類(lèi)(object)的new方法創(chuàng)建一個(gè)該類(lèi)(cls==Singleton)的實(shí)例。
          Singleton._instance = object.__new__(cls)
          return Singleton._instance

          obj1 = Singleton()
          obj2 = Singleton()
          print(obj1,obj2)

          def task(arg):
          obj = Singleton()
          print(obj)

          for i in range(10):
          t = threading.Thread(target=task,args=[i,])
          t.start()

          11. 請(qǐng)描述抽象類(lèi)和接口類(lèi)的區(qū)別和聯(lián)系

          1.抽象類(lèi):規(guī)定了一系列的方法,并規(guī)定了必須由繼承類(lèi)實(shí)現(xiàn)的方法。由于有抽象方法的存在,所以抽象類(lèi)不能實(shí)例化。
          可以將抽象類(lèi)理解為毛坯房,門(mén)窗,墻面的樣式由你自己來(lái)定,所以抽象類(lèi)與作為基類(lèi)的普通類(lèi)的區(qū)別在于約束性更強(qiáng)。
          2.接口類(lèi):與抽象類(lèi)很相似,表現(xiàn)在接口中定義的方法,必須由引用類(lèi)實(shí)現(xiàn),但他與抽象類(lèi)的根本區(qū)別在于用途:
          與不同個(gè)體間溝通的規(guī)則,你要進(jìn)宿舍需要有鑰匙,這個(gè)鑰匙就是你與宿舍的接口,你的舍友也有這個(gè)接口,
          所以他也能進(jìn)入宿舍,你用手機(jī)通話(huà),那么手機(jī)就是你與他人交流的接口。
          3.區(qū)別和關(guān)聯(lián):
          a.接口是抽象類(lèi)的變體,接口中所有的方法都是抽象的,而抽象類(lèi)中可以有非抽象方法,抽象類(lèi)是聲明方法的存在而不去實(shí)現(xiàn)它的類(lèi);
          b.接口可以繼承,抽象類(lèi)不行;
          c.接口定義方法,沒(méi)有實(shí)現(xiàn)的代碼,而抽象類(lèi)可以實(shí)現(xiàn)部分方法;
          d.接口中基本數(shù)據(jù)類(lèi)型為static而抽象類(lèi)不是;

          12. 編寫(xiě)函數(shù)的4個(gè)原則

          1.函數(shù)設(shè)計(jì)要盡量短小;
          2.函數(shù)聲明要做到合理、簡(jiǎn)單、易于使用;
          3.函數(shù)參數(shù)設(shè)計(jì)應(yīng)該考慮向下兼容;
          4.一個(gè)函數(shù)只做一件事情,盡量保證函數(shù)語(yǔ)句粒度的一致性;

          13. 什么是lambda函數(shù)?有什么好處?

          lambda 函數(shù)是一個(gè)可以接收任意多個(gè)參數(shù)(包括可選參數(shù))并且返回單個(gè)表達(dá)式值的函數(shù);
          1.lambda函數(shù)比較輕便,即用即
          扔,很適合需要完成一項(xiàng)功能,但是此功能只在此一處使用,連名字都很隨意的情況下;
          2.匿名函數(shù),一般用來(lái)給filter,map這樣的函數(shù)式編程服務(wù);
          3.作為回調(diào)函數(shù),傳遞給某些應(yīng)用,比如消息處理;

          14. 什么是閉包

          在函數(shù)內(nèi)部再定義一個(gè)函數(shù),并且這個(gè)函數(shù)用到了外邊函數(shù)的變量,那么將這個(gè)函數(shù)以及用到的一些變量稱(chēng)之為閉包。

          15. Python中的yield

          yield類(lèi)似return會(huì)停止,但是不會(huì)結(jié)束。yield作為可迭代的 generator(生成器)對(duì)象,
          每次迭代的時(shí)候會(huì)在yield語(yǔ)句后停止
          def simple_generator():
          x = 2
          yield x**2
          yield x**3
          yield x**4

          generator_object = simple_generator()
          [item for item in generator_object]
          #[4, 8, 16]

          16. Python實(shí)現(xiàn)私用變量的效果

          1. 單下劃線(xiàn)表示的私有,但是依然可以直接訪(fǎng)問(wèn);
          2. 雙下劃線(xiàn)表示的私有,因?yàn)楸粡?qiáng)制改名,所以不可以直接訪(fǎng)問(wèn),但訪(fǎng)問(wèn)這個(gè)改成的變量名;
          class Rect:
          def __init__(self,area):
          self.__area = area
          @property
          def area(self):
          return self.__area
          rect = Rect(30)
          #直接通過(guò)方法名來(lái)訪(fǎng)問(wèn) area 方法
          print("矩形的面積是:",rect.area)
          #假私有,_Rect__area就是__area新的變量名。
          rect._Rect__area

          17. 進(jìn)程、線(xiàn)程、協(xié)程

          進(jìn)程:程序運(yùn)行在操作系統(tǒng)上的一個(gè)實(shí)例,就稱(chēng)之為進(jìn)程。進(jìn)程需要相應(yīng)的系統(tǒng)資源:內(nèi)存、時(shí)間片、pid
          一個(gè)運(yùn)行的程序就是一個(gè)進(jìn)程,沒(méi)有運(yùn)行的代碼叫程序。
          進(jìn)程是系統(tǒng)資源分配的最小單位,進(jìn)程擁有自己獨(dú)立的內(nèi)存空間,所有進(jìn)程間數(shù)據(jù)不共享,且開(kāi)銷(xiāo)大。

          多進(jìn)程:適合CPU密集操作cpu指令比較多,如位多的浮點(diǎn)運(yùn)算)。

          線(xiàn)程:cpu調(diào)度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨(dú)立存在,依賴(lài)進(jìn)程存在。一個(gè)進(jìn)程至少有一個(gè)線(xiàn)程,叫做主線(xiàn)程。
          而多個(gè)線(xiàn)程共享內(nèi)存(數(shù)據(jù)共享,共享全局變量),從而極大的提高了程序的運(yùn)行效率。

          多線(xiàn)程:適合IO密集性操作(讀寫(xiě)數(shù)據(jù)操作比較多的,比如爬蟲(chóng));

          協(xié)程:是一種用戶(hù)態(tài)的輕量級(jí)線(xiàn)程,協(xié)程的調(diào)度完全由用戶(hù)控制。協(xié)程擁有自己的寄存器上下文和棧。
          協(xié)程調(diào)度時(shí),將寄存器上下文和棧保存到其它地方,在切回來(lái)的時(shí)候,恢復(fù)先前保存的寄存器上下文和棧,
          直接操作棧基本沒(méi)有內(nèi)核切換的開(kāi)銷(xiāo),可以不加鎖的訪(fǎng)問(wèn)全局變量,所以上下文的切換非常快。

          三者關(guān)系:進(jìn)程里面有線(xiàn)程,線(xiàn)程里面有協(xié)程。
          線(xiàn)程是并發(fā),進(jìn)程是并行。

          并行:同一時(shí)刻多個(gè)任務(wù)同時(shí)運(yùn)行;
          并發(fā):不會(huì)在同一時(shí)刻同時(shí)運(yùn)行,存在交替執(zhí)行的情況。

          18. Python異步的使用場(chǎng)景

          1. 不涉及共享資源,或者對(duì)于共享資源只讀等非互斥操作;
          2. 沒(méi)有時(shí)序上的嚴(yán)格關(guān)系;
          3. 不需要原子操作,或可以通過(guò)其它方式控制原子性;
          4. 常用于IO操作等耗時(shí)操作,因?yàn)楸容^影響客戶(hù)體驗(yàn)和使用性能;
          5. 不影響主線(xiàn)程邏輯。
          所謂原子操作是指不會(huì)被 線(xiàn)程調(diào)度 機(jī)制打斷的操作;這種操作一旦開(kāi)始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何 context switch (切換到另一個(gè)線(xiàn)程)。

          19. 什么是多線(xiàn)程競(jìng)爭(zhēng)

          線(xiàn)程是非獨(dú)立的,同一個(gè)進(jìn)程里線(xiàn)程是數(shù)據(jù)共享的,當(dāng)各個(gè)線(xiàn)程訪(fǎng)問(wèn)數(shù)據(jù)資源時(shí)會(huì)出現(xiàn)競(jìng)爭(zhēng)狀態(tài),
          即:數(shù)據(jù)幾乎同步被多個(gè)線(xiàn)程占有,造成數(shù)據(jù)混亂,即所謂的線(xiàn)程不安全。為此可添加鎖。

          鎖是Python提供的對(duì)線(xiàn)程控制的對(duì)象。有互斥鎖,可重入鎖,死鎖。
          鎖的好處:確保某段關(guān)鍵代碼(共享數(shù)據(jù)資源)只能由一個(gè)線(xiàn)程從頭到尾完整地執(zhí)行;能解決資源競(jìng)爭(zhēng)下的原子操作問(wèn)題。
          鎖的壞處:阻止了多線(xiàn)程并發(fā)執(zhí)行,包含鎖的某段代碼實(shí)際上只能以單線(xiàn)程模式執(zhí)行,效率大大下降。

          20. Python的線(xiàn)程同步

          1. setDaemon(False),當(dāng)一個(gè)進(jìn)程啟動(dòng)之后,會(huì)默認(rèn)產(chǎn)生一個(gè)主線(xiàn)程,因?yàn)榫€(xiàn)程時(shí)程序執(zhí)行的最小單位。
          當(dāng)設(shè)置多線(xiàn)程時(shí),主線(xiàn)程會(huì)創(chuàng)建多個(gè)子線(xiàn)程。在Python中,默認(rèn)情況下就是setDaemon(False),
          主線(xiàn)程執(zhí)行完自己的任務(wù)以后就退出。此時(shí)子線(xiàn)程會(huì)繼續(xù)執(zhí)行自己的任務(wù),直到自己的任務(wù)結(jié)束。

          2. setDaemon(True),這時(shí)子線(xiàn)程為守護(hù)線(xiàn)程,主線(xiàn)程一旦執(zhí)行結(jié)束,則全部子線(xiàn)程被強(qiáng)制終止。

          3. join(線(xiàn)程同步),join所完成的工作就是線(xiàn)程同步,即主線(xiàn)程任務(wù)結(jié)束以后,進(jìn)入堵塞狀態(tài),
          一直等待所有的子線(xiàn)程結(jié)束以后,主線(xiàn)程再終止。
          當(dāng)設(shè)置守護(hù)線(xiàn)程時(shí),含義是主線(xiàn)程對(duì)于子線(xiàn)程等待timeout的時(shí)間將會(huì)殺死該子線(xiàn)程,最后退出程序。
          所以說(shuō),如果有10個(gè)子線(xiàn)程,全部等待時(shí)間就是每個(gè)timeout的累加和
          如果沒(méi)有設(shè)置守護(hù)線(xiàn)程時(shí),主線(xiàn)程將會(huì)等待timeout的累加和這樣的一段時(shí)間,時(shí)間一到,主線(xiàn)程結(jié)束,
          但是子線(xiàn)程依然存活,并且持續(xù)運(yùn)行,直到子線(xiàn)程全部結(jié)束,程序退出。(孤兒進(jìn)程)
          import threading
          import time

          def thread():
          time.sleep(2)
          print('---子線(xiàn)程結(jié)束---')

          def main():
          t1 = threading.Thread(target=thread)
          t1.setDaemon(True) # 設(shè)置子線(xiàn)程守護(hù)主線(xiàn)程
          t1.start()
          t1.join(timeout=1) # 線(xiàn)程同步,主線(xiàn)程堵塞1s,然后主線(xiàn)程結(jié)束,子線(xiàn)程繼續(xù)執(zhí)行;
          # 如果不設(shè)置timeout參數(shù)就等子線(xiàn)程結(jié)束后主線(xiàn)程再結(jié)束;
          # 如果設(shè)置了setDaemon=True和timeout=1主線(xiàn)程等待1s后會(huì)強(qiáng)制殺死子線(xiàn)程,然后主線(xiàn)程結(jié)束。
          print('---主線(xiàn)程結(jié)束---')

          main()

          21. 死鎖

          定義:若干子線(xiàn)程在系統(tǒng)資源競(jìng)爭(zhēng)的時(shí)候,都在等待對(duì)方對(duì)某部分資源解除占用狀態(tài),結(jié)果誰(shuí)也不愿意先解鎖,程序無(wú)法執(zhí)行下去。
          GIL鎖:全局解釋器鎖;
          作用:限制多線(xiàn)程同時(shí)執(zhí)行,保證同一時(shí)間只有一個(gè)線(xiàn)程執(zhí)行,所以cpython里的多線(xiàn)程其實(shí)是偽多線(xiàn)程。
          python里常常使用協(xié)程技術(shù)來(lái)代替多線(xiàn)程,協(xié)程是一種更輕量級(jí)的線(xiàn)程。
          進(jìn)程和線(xiàn)程的切換是由系統(tǒng)決定,而協(xié)程由開(kāi)發(fā)者決定,而模塊gevent下切換是遇到了耗時(shí)操作時(shí)才會(huì)切換。

          22. 多線(xiàn)程交互訪(fǎng)問(wèn)數(shù)據(jù),如何避免重讀。

          創(chuàng)建一個(gè)已訪(fǎng)問(wèn)數(shù)據(jù)列表,用于存儲(chǔ)已經(jīng)訪(fǎng)問(wèn)過(guò)的數(shù)據(jù),并加上互斥鎖,
          在多線(xiàn)程訪(fǎng)問(wèn)數(shù)據(jù)的時(shí)候先查看數(shù)據(jù)是否在已訪(fǎng)問(wèn)的列表中,若存在就跳過(guò)。

          23. 線(xiàn)程安全、互斥鎖

          每個(gè)對(duì)象都對(duì)應(yīng)于一個(gè)可稱(chēng)為”互斥鎖“的標(biāo)記,這個(gè)標(biāo)記用來(lái)保證在任一時(shí)刻,只能有一個(gè)線(xiàn)程訪(fǎng)問(wèn)該對(duì)象。
          同一進(jìn)程中的多線(xiàn)程之間共享系統(tǒng)資源,多個(gè)線(xiàn)程同時(shí)對(duì)一個(gè)對(duì)象進(jìn)行操作,一個(gè)線(xiàn)程操作尚未結(jié)束,另一線(xiàn)程已經(jīng)對(duì)其進(jìn)行操作,
          導(dǎo)致最終結(jié)果出現(xiàn)錯(cuò)誤,此時(shí)需要對(duì)被操作對(duì)象添加互斥鎖,保證每個(gè)線(xiàn)程對(duì)該對(duì)象的操作都得到正確的結(jié)果。

          24. 同步、異步、阻塞,非阻塞

          同步:多個(gè)任務(wù)之間有先后執(zhí)行順序,一個(gè)執(zhí)行完下個(gè)才能執(zhí)行。
          異步:多個(gè)任務(wù)之間沒(méi)有先后順序,可以同時(shí)執(zhí)行,有時(shí)候一個(gè)任務(wù)可能要在必要的時(shí)候獲取另一個(gè)同時(shí)執(zhí)行的任務(wù)結(jié)果(回調(diào)操作)。
          阻塞:如果卡住了調(diào)用者,調(diào)用者不能繼續(xù)往下執(zhí)行,指的就是調(diào)用者發(fā)生阻塞。
          非阻塞:如果不會(huì)卡住,可以繼續(xù)執(zhí)行,指的就是非阻塞。
          同步、異步相對(duì)于多任務(wù)而言,阻塞非阻塞相對(duì)于代碼執(zhí)行而言。

          25. 什么是僵尸進(jìn)程、孤兒進(jìn)程

          孤兒進(jìn)程:父進(jìn)程退出,子進(jìn)程還在運(yùn)行的這些子進(jìn)程都是孤兒進(jìn)程,孤兒進(jìn)程將被init進(jìn)程(進(jìn)程號(hào)為1)所收養(yǎng),
          并由init進(jìn)程對(duì)他們的完成狀態(tài)進(jìn)行收集。
          僵尸進(jìn)程:進(jìn)程使用fork創(chuàng)建子進(jìn)程,如果子進(jìn)程退出,而父進(jìn)程并沒(méi)有調(diào)用wait/waitpid獲取子進(jìn)程的狀態(tài)信息,
          那么子進(jìn)程的進(jìn)程描述符仍然保存在系統(tǒng)中的這些進(jìn)程。

          避免僵尸進(jìn)程的方法:
          1. fork兩次用孫子進(jìn)程去完成子進(jìn)程的任務(wù);
          2. 用wait()函數(shù)使父進(jìn)程阻塞;
          3. 使用信號(hào)量,在signal handler中調(diào)用waitpid,這樣父進(jìn)程不用阻塞。

          26. 多線(xiàn)程共同操作同一個(gè)數(shù)據(jù)互斥鎖同步

          上鎖解鎖過(guò)程
          當(dāng)一個(gè)線(xiàn)程調(diào)用鎖的 acquire() 方法獲得鎖時(shí),鎖就進(jìn)入“locked”狀態(tài)。
          每次只有一個(gè)線(xiàn)程可以獲得鎖。
          如果此時(shí)另一個(gè)線(xiàn)程試圖獲得這個(gè)鎖,該線(xiàn)程就會(huì)變?yōu)椤?/span>blocked”狀態(tài),稱(chēng)為“阻塞”,
          直到擁有鎖的線(xiàn)程調(diào)用鎖的 release() 方法釋放鎖之后,鎖進(jìn)入“unlocked”狀態(tài)。
          線(xiàn)程調(diào)度程序從處于同步阻塞狀態(tài)的線(xiàn)程中選擇一個(gè)來(lái)獲得鎖,并使得該線(xiàn)程進(jìn)入運(yùn)行(running)狀態(tài)。

          import threading
          import time

          g_num = 0

          def test1(num):
          global g_num
          for i in range(num):
          mutex.acquire() # 上鎖
          g_num += 1
          mutex.release() # 解鎖

          print("---test1---g_num=%d" % g_num)

          def test2(num):
          global g_num
          for i in range(num):
          mutex.acquire() # 上鎖
          g_num += 1
          mutex.release() # 解鎖

          print("---test2---g_num=%d" % g_num)

          # 創(chuàng)建一個(gè)互斥鎖
          # 默認(rèn)是未上鎖的狀態(tài)
          mutex = threading.Lock()

          # 創(chuàng)建2個(gè)線(xiàn)程,讓他們各自對(duì)g_num加10000次
          p1 = threading.Thread(target=test1, args=(10000,))
          p1.start()

          p2 = threading.Thread(target=test2, args=(10000,))
          p2.start()

          """
          enumerate() 是 Python 中線(xiàn)程模塊的內(nèi)置方法。
          它用于返回當(dāng)前處于活動(dòng)狀態(tài)的所有 Thread 類(lèi)對(duì)象的列表。
          它還包括守護(hù)線(xiàn)程、主線(xiàn)程和由 current_thread() 創(chuàng)建的虛擬線(xiàn)程對(duì)象。
          它不計(jì)算已終止或尚未啟動(dòng)的線(xiàn)程。
          """
          # 等待計(jì)算完成
          while len(threading.enumerate()) != 1:
          time.sleep(0.1)

          print("2個(gè)線(xiàn)程對(duì)同一個(gè)全局變量操作之后的最終結(jié)果是:%s" % g_num)

          27. 進(jìn)程通信隊(duì)列與進(jìn)程池

          由于不同進(jìn)程之間不通信,所以采用隊(duì)列。
          由于需要控制進(jìn)程數(shù)量,所以有了進(jìn)程池。過(guò)多的進(jìn)程數(shù)量并不高效。

          def read_data(queue):
          # 循環(huán)讀取數(shù)據(jù)
          while True:
          # 判斷隊(duì)列是否為空
          if queue.qsize() == 0:
          print("隊(duì)列為空~")
          break
          # 從隊(duì)列中讀取數(shù)據(jù)
          result = queue.get()
          print(result)


          if __name__ == '__main__':
          # 創(chuàng)建進(jìn)程池
          pool = multiprocessing.Pool(2)
          # 創(chuàng)建進(jìn)程池隊(duì)列
          queue = multiprocessing.Manager().Queue()
          # 在進(jìn)程池中的進(jìn)程間進(jìn)行通信
          # 使用線(xiàn)程池同步的方式,先寫(xiě)后讀
          # pool.apply(write_data, (queue, )) # 同步方式加載
          # pool.apply(read_data, (queue, )) # 同步方式加載
          # apply_async() 返回ApplyResult 對(duì)象
          result = pool.apply_async(write_data, (queue, )) # 異步方式加載
          # ApplyResult對(duì)象的wait() 方法,表示后續(xù)進(jìn)程必須等待當(dāng)前進(jìn)程執(zhí)行完再繼續(xù)
          result.wait() # 由于異步方式加載,但是必須寫(xiě)先完成,所以必須等待寫(xiě)進(jìn)程完成
          pool.apply_async(read_data, (queue, )) # 異步方式加載
          pool.close()
          # 異步后,主線(xiàn)程不再等待子進(jìn)程執(zhí)行結(jié)束,再結(jié)束
          # join() 后,表示主線(xiàn)程會(huì)等待子進(jìn)程執(zhí)行結(jié)束后,再結(jié)束
          pool.join()

          公眾號(hào)粉絲禮包:后臺(tái)關(guān)鍵詞:

          python大禮包

          整理不易,還請(qǐng)點(diǎn)擊在看與分享,謝謝。

          瀏覽 63
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲 欧美 另类 综合 偷拍 | 天天射网| 亚洲欧美第一页 | 影音先锋AV一区二区三区 | 欧美在线观看黄片 |