<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 進程狀態 ![](https://box.kancloud.cn/12d1215f70c332d1bd4839cd0a9967ed_662x216.png) * 就緒狀態: 運行的條件都已經滿足,正在等待cpu執行 * 執行態: cpu正在執行其功能 * 等待態: 等待某些條件滿足,例如一個程序sleep了,此時就處于等待態 # fork方式 Unix/Linux操作系統提供了一個fork()系統調用,它非常特殊。普通的函數調用,調用一次,返回一次,但是fork()調用一次,返回兩次,因為操作系統自動把當前進程(稱為父進程)復制了一份(稱為子進程),然后,分別在父進程和子進程內返回。 子進程永遠返回0,而父進程返回子進程的ID。這樣做的理由是,一個父進程可以fork出很多子進程,所以,父進程要記下每個子進程的ID,而子進程只需要調用getppid()就可以拿到父進程的ID ~~~ import os # 表示父進程開始了 print('Process (%s) start...' % os.getpid()) # 只能unix和linux和mac pid = os.fork() if pid == 0: # 子進程 print('我是子進程,進程id是 (%s) , 父進程的id是 (%s)' % (os.getpid(), os.getppid())) else: # 父進程 print('我是父進程,進程id是 (%s) , 我創建的子進程id是 (%s) ' % (os.getpid(), pid)) ~~~ 輸?出 ~~~ Process (32454) start... 我是父進程,進程id是 (32454) , 我創建的子進程id是 (32458) 我是子進程,進程id是 (32458) , 父進程的id是 (32454) ~~~ 由于Windows沒有fork調用,上面的代碼在Windows上無法運行 # multiprocessing multiprocessing模塊就是跨平臺版本的多進程模塊 multiprocessing模塊提供了一個Process類來代表一個進程對象,下面的例子演示了啟動一個子進程并等待其結束: ~~~ import multiprocessing import os # 子進程要執行的代碼 def run_proc(name): print('子進程的參數name是 (%s) , id是 (%s) ' % (name, os.getpid())) if __name__ == '__main__': print('父進程的id是 (%s)' % os.getpid()) p = multiprocessing.Process(target=run_proc, args=('test', )) print('子進程將要開始了...') p.start() p.join() print('子進程結束...') ~~~ 輸?出 ~~~ 父進程的id是 (32564) 子進程將要開始了... 子進程的參數name是 (test) , id是 (32568) 子進程結束... ~~~ 創建子進程時,只需要傳入一個執行函數和函數的參數,創建一個Process實例,用start()方法啟動,這樣創建進程比fork()還要簡單。 join()方法可以等待子進程結束后再繼續往下運行,通常用于進程間的同步 # Pool進程池 如果要啟動大量的子進程,可以用進程池的方式批量創建子進程 ~~~ import multiprocessing import os, time, random def long_time_task(name): print('參數name:(%s),子進程id是(%s)' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('參數name:(%s),運行了 %0.2f 秒' % (name, (end - start))) if __name__ == '__main__': print('父進程的id是 (%s)' % os.getpid()) # 創建4個子進程 p = multiprocessing.Pool(4) # 循環5次,投遞5個任務給這些子進程 for i in range(5): p.apply_async(long_time_task, args=(i, )) print('等待所有進程結束') # 關閉進程池,關閉后不再接收新的請求 p.close() # 等待po中所有子進程執行完成,必須放在close之后 p.join() print('所有進程結束') ~~~ 輸?出 ~~~ 父進程的id是 (35744) 等待所有進程結束 參數name:(0),子進程id是(35749) 參數name:(1),子進程id是(35750) 參數name:(2),子進程id是(35751) 參數name:(3),子進程id是(35752) 參數name:(2),運行了 1.57 秒 參數name:(4),子進程id是(35751) 參數name:(3),運行了 2.22 秒 參數name:(0),運行了 2.76 秒 參數name:(1),運行了 2.94 秒 參數name:(4),運行了 2.54 秒 所有進程結束 ~~~ 代碼解讀: 對Pool對象調用join()方法會等待所有子進程執行完畢,調用join()之前必須先調用close(),調用close()之后就不能繼續添加新的Process了。 請注意輸出的結果,task 0,1,2,3是立刻執行的,而task 4要等待前面某個task完成后才執行,這是因為Pool的默認大小在我的電腦上是4,因此,最多同時執行4個進程。這是Pool有意設計的限制,并不是操作系統的限制。如果改成 # 控制子進程輸入和輸出 很多時候,子進程并不是自身,而是一個外部進程。我們創建了子進程后,還需要控制子進程的輸入和輸出。 subprocess模塊可以讓我們非常方便地啟動一個子進程,然后控制其輸入和輸出 下面的例子演示了如何在Python代碼中運行命令`nslookup www.python.org`(查詢域名的DNS解析),這和命令行直接運行的效果是一樣的 ~~~ import subprocess print('$ nslookup www.python.org') r = subprocess.call(['nslookup', 'www.python.org']) print('結束的狀態碼:', r) ~~~ 輸?出 ~~~ $ nslookup www.python.org Server: 192.168.3.1 Address: 192.168.3.1#53 Non-authoritative answer: www.python.org canonical name = dualstack.python.map.fastly.net. Name: dualstack.python.map.fastly.net Address: 151.101.108.223 結束的狀態碼: 0 ~~~ 如果子進程還需要輸入,則可以通過communicate()方法輸入 ~~~ import subprocess print('$ nslookup') p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = p.communicate(b'set q=mx\npython.org\nexit\n') print(output.decode('utf-8')) print('Exit code:', p.returncode) ~~~ 上面的代碼相當于在命令行執行命令nslookup,然后手動輸入 ~~~ set q=mx python.org exit ~~~ 運行結果如下: ~~~ $ nslookup Server: 192.168.19.4 Address: 192.168.19.4#53 Non-authoritative answer: python.org mail exchanger = 50 mail.python.org. Authoritative answers can be found from: mail.python.org internet address = 82.94.164.166 mail.python.org has AAAA address 2001:888:2000:d::a6 Exit code: 0 ~~~ # 進程間通信 Process之間肯定是需要通信的,操作系統提供了很多機制來實現進程間的通信。Python的multiprocessing模塊包裝了底層的機制,提供了Queue、Pipes等多種方式來交換數據。 **常?用方法** ~~~ # 創建隊列,可以指定容量 q = multiprocessing.Queue() # 隊列是不是滿的 ?q.full() # 獲取數據 ?q.get() # 隊列是不是空 ?q.empty() # 寫入數據 q.put(xx) ~~~ 我們以Queue為例,在父進程中創建兩個子進程,一個往Queue里寫數據,一個從Queue里讀數據 ~~~ import multiprocessing import os, time, random # 寫數據進程執行的代碼 def write(q): print('進程id (%s) 正在寫入' % os.getpid()) for value in ['A', 'B', 'C']: print('把(%s)放到隊列...' % value) q.put(value) time.sleep(random.random()) # 讀數據進程執行的代碼 def read(q): print('進程id (%s) 正在讀取' % os.getpid()) while True: value = q.get(True) print('獲取(%s)從隊列中' % value) if __name__ == '__main__': # 父進程創建queue,并傳給各個子進程 q = multiprocessing.Queue() pw = multiprocessing.Process(target=write, args=(q, )) pr = multiprocessing.Process(target=read, args=(q, )) # 啟動子進程pw,寫入: pw.start() # 啟動子進程pr,寫入: pr.start() # 等待pw結束 pw.join() # pr進程里是死循環,無法等待其結束,只能強行終止 pr.terminate() ~~~ 輸?出 ~~~ 進程id (36109) 正在寫入 把(A)放到隊列... 進程id (36110) 正在讀取 獲取(A)從隊列中 把(B)放到隊列... 獲取(B)從隊列中 把(C)放到隊列... 獲取(C)從隊列中 ~~~ 在Unix/Linux下,multiprocessing模塊封裝了fork()調用,使我們不需要關注fork()的細節。由于Windows沒有fork調用,因此,multiprocessing需要“模擬”出fork的效果,父進程所有Python對象都必須通過pickle序列化再傳到子進程去,所有,如果multiprocessing在Windows下調用失敗了,要先考慮是不是pickle失敗了
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看