SlideShare uma empresa Scribd logo
1 de 81
Baixar para ler offline
13.並行、平行與非同步
• 學習目標
– 認識並行、平行與非同步
– 使用 threading 模組
– 使用 multiprocessing 模組
– 使用 concurrent.futures模組
– 運用 async、await 與 asyncio
2
並行
• 多個流程可以並行(Concurrency)處理,
也就是從使用者的觀點來看,會是同時
「執行」各個流程
• 然而實際上,是同時「管理」多個流程
3
簡介執行緒
4
5
• 雖可以繼承 threading.Thread, 在
__init__()呼叫 super().__init__(),
並在類別中定義run()方法來實作執行緒
• 不過是不建議的,因為這會使得你的流程與
threading.Thread 產生相依性
6
7
8
• python 直譯器同時間只允許執行一個執行
緒,因此並不是真正的平行(Parallel)處
理,只不過「有時候」切換速度快到人類
感覺上像是同時處理罷了
• 執行緒適用的場合之一,就是非計算密集
的場合,因為與其等待某個阻斷作業完成,
不如趁著等待的時間來進行其他執行緒
9
10
11
• 對於計算密集的任務,使用執行緒不見得
會提高處理效率,反而容易因為直譯器必
須切換執行緒而耗費不必要的成本,使得
效率變差。
12
• 如果主執行緒中啟動了額外執行緒,預設
會等待被啟動的所有執行緒都執行完才中
止程式。
• 如果一個 Thread 建立時,指定了daemon
參數為 True,在所有的非 Daemon 的執
行緒都結束時,程式就會直接終止
• 如果需要在背景執行一些常駐任務,就可
以指定 daemon 參數為 True。
13
• 當執行緒使用 join() 加入至另一執行緒
時,另一執行緒會等待被加入的執行緒工
作完畢,然後再繼續它的動作
14
• 如果要停止執行緒,必須自行實作,讓執
行緒跑完應有的流程
15
競速、鎖定、死結
• 如果執行緒之間不需要共享資料, 或者共
享的資料是不可變動(Immutable)的型
態,事情會單純一些
• 然而,執行緒之間經常得共用一些可變動
狀態的資料…
• 要是執行緒之間需要共享的是可變動狀態
的資料,就會有可能發生競速狀況…
16
17
• 若要避免競速的情況發生,就必須資源被
變更與取用時的關鍵程式碼進行鎖定
18
19
• threading.Lock 實作了情境管理器協定,
可以搭配 with 來簡化 acquire() 與
release() 的呼叫
20
21
• 執行緒無法取得鎖定時會造成阻斷,不正
確地使用 Lock 有可能造成效能低落,另一
問題則是死結
22
23
• threading.RLock 實現了可重入鎖
(Reentrant lock)
• 同一執行緒可以重複呼叫同一個
threading.RLock 實例的 acquire()
而不被阻斷
• release()時也要有對應於 acquire()
的次數,方可以完全解除鎖定
• threading.RLock 也實作了情境管理器
協定,可搭配 with 來使用
24
• 另一個經常使用的鎖定機制是
threading.Condition
• 某個執行緒在透過 acquire() 取得鎖定之
後,若需要在特定條件符合之前等待,可
以呼叫 wait() 方法,這會釋放鎖定
• 若其他執行緒的運作促成特定條件成立,
可以呼叫同一 threading.Condition 實
例的 notify(),通知等待條件的一個執
行緒可取得鎖定
25
• 若等待中的執行緒取得鎖定,就會從上次
呼叫 wait() 方法處繼續執行
• 如果等待中的執行緒有多個,還可以呼叫
notify_all(),這會通知全部等待中的
執行緒爭取鎖定
26
27
28
• 如果需要這種一進一出,在執行緒之間交
換資料的方式,Python 標準程式庫中提供
了 queue.Queue
29
• 建立Semaphore 可指定計數器初始值
• 每呼叫一次 acquire(),計數器值遞減一,
在計數器為0 時若呼叫了 acquire(),執
行緒就會被阻斷
• 每呼叫一次 release(),計數器值遞增一,
如果 release()前計數器為 0,而且有執
行緒正在等待,在 release() 並遞增計數
器之後,會通知等待中的執行緒
30
• 可以設定一個 Barrier 並指定數量
• 如果有執行緒先來到這個柵欄,它必須等
待其他執行緒也來到這個柵欄
• 指定的執行緒數量達到,全部執行緒才能
繼續往下執行
31
32
平行
• 針對計算密集式的運算,若能在一個新的
行程(Process)平行(Parallel)運行,在
今日電腦普遍都有多個核心的情況下,就
有機會跑得更快一些。
33
• subprocess 模組可以讓你在執行 Python
程式的過程中,產生新的子行程
34
• 從 Python 3.5 開始,建議使用 run() 函
式來呼叫子行程
• subprocess.run() 執行之後會傳回
CompletedProcess 實例
• 若想要能取得標準輸出的執行結果:
35
• 如果子行程必須接受標準輸入:
36
• subprocess.run() 的底層是透過
subprocess.Popen() 實作出來的
37
• subprocess.Popen() 執行程式,會立
即傳回 Popen 實例,不會等待子行程結束
38
39
• 如果想要以子行程來執行函式,然而使用
類似 threading 模組的 API 介面,那麼
可以使用 multiprocessing 模組
40
41
• 建議在使用 multiprocessing 模組時,
最好的方式是不要共享狀態
• 然而有時行程之間難免需要進行溝通,
multiprocessing.Queue 是執行緒與行
程安全的,實作了必要的鎖定機制
42
43
44
• multiprocessing.Lock 也實作了情境
管理器協定
45
46
非同步
• Python 3.2 新增 concurrent.futures
模組,它提供了執行緒或行程高階封裝,
也便於實現非同步的任務
• 從 Python 3.5 之後,提供了async、
await 等語法,以及 asyncio 模組的支援,
如果非同步任務涉及大量的輸入輸出,可
以善用這些特性
47
使用 concurrent.futures
• 提供了 ThreadPoolExecutor 與
ProcessPoolExecutor 等高階API,分
別為執行緒與行程提供了工作者池的服務
48
49
• 對於計算密集式的任務,可以使用
ProcessPoolExecutor
50
51
• 使用 map() 方法來簡化程式的撰寫
52
Future 與非同步
• 獨立於程式主流程的任務、事件生成,以
及處理事件的方式,稱為非同步
• 使用執行緒或行程時,若想實現非同步概
念,方式之一是採用註冊回呼函式
53
54
• executor 的submit() 執行過後會傳回
Future,擁有 add_done_callback()
55
• 在下載的同時實現簡單的進度列:
56
略談 yield from 與非同步
57
• 若後續處理為數個非同步函式的話,整個
流程會馬上陷入難以理解的狀態
• Python 3.3 時新增了 yield from 語法,
Python 3.4 的 asyncio 與某些第三方程式
庫,曾基於這個語法提出了解決方案
• Python 3.5 後建議不要使用 yield from,
建議使用 async、await
58
59
yield from 與 Future
60
• 有多個非同步函式,顯然就需要個迴圈:
61
• 程式執行雖然是非同步,然而撰寫風格上
卻像是循序
• 若有人想呼叫 asyncTasks() 呢?甚至是
在流程上組合多個這類的函式?
62
63
64
Asyncio與並行
• 並非一定要多執行緒或多行程,才能實現
並行
• 多執行緒或多行程只是實現並行比較容易
• 只要執行環境支援,在單一行程、單一執
行緒中,也有可能實現並行
– 在遇到阻斷操作時會讓出(yield)流程控制權
給呼叫函式者,那呼叫函式的一方,就可以繼
續下個並行任務的啟動
65
• 如果在定義函式時,加上了 async 關鍵字,
呼叫該函式並不會馬上執行函式流程,而
是傳回一個 coroutine 物件
• 想要執行函式中定義的流程,可以透過
asyncio.run() 函式
66
• async def定義的函式是個非同步任務
• 執行asyncio.run()會阻斷,直到該執行
緒完成指定的任務
• 如果有多個任務要指定呢?Python 3.7以
後可以使用asyncio.create_task()
67
• 必須在async def函式中呼叫
asyncio.create_task()
• 也就是說,若有多個要執行的非同步任務,
必須在async def的函式中組織
• asyncio.create_task()不會阻斷執行
緒
68
69
事件迴圈
• 大部份基於Asyncio的函式,建議使用
asyncio.run()來執行
• 在Python 3.7之前沒有
asyncio.create_task(),就是透過這種
方式來建立多個任務
70
• 方才第二個REPL範例,若要直接操作事件
迴圈
71
• 在Python 3.7以後,若不想傳遞事件迴圈
實例給async def函式,可以使用
asyncio.get_running_loop()
72
async、await 與非同步
• async 用來標示函式執行時是非同步,也
就是函式中定義定義了獨立於程式主流程
的任務
• 後續若要在任務完成時,做進一步的處理
也是可行的
• 從 Python 3.5 開始,可以使用await
73
74
• 就語義上,若想等待 async 函式執行完後,
再執行後續的流程,可以使用await
• async 函式的任務完成後若有傳回值,會
成為 await 的傳回值
75
76
77
非同步產生器與 async for
78
• 迭代產生器時會以阻斷方式讀取 URL 後傳
回 bytes
79
情境管理器與 async with
80
81

Mais conteúdo relacionado

Mais procurados

Ansibleの最近の動向を追ってみた
Ansibleの最近の動向を追ってみたAnsibleの最近の動向を追ってみた
Ansibleの最近の動向を追ってみたKeijiUehata1
 
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)基信 高橋
 
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
10年効く分散ファイルシステム技術 GlusterFS & Red Hat StorageEtsuji Nakai
 
AHVでみるCVM Autopathの仕組み
AHVでみるCVM Autopathの仕組みAHVでみるCVM Autopathの仕組み
AHVでみるCVM Autopathの仕組みKazuhito Ohkawa
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)AtCoder Inc.
 
Androidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリAndroidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリYukiya Nakagawa
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコルMITSUNARI Shigeo
 
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習Hori Tasuku
 
AWSで透過プロキシをやってみた
AWSで透過プロキシをやってみたAWSで透過プロキシをやってみた
AWSで透過プロキシをやってみたkuro kuro
 
Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Ryuichi Sakamoto
 
インメモリーで超高速処理を実現する場合のカギ
インメモリーで超高速処理を実現する場合のカギインメモリーで超高速処理を実現する場合のカギ
インメモリーで超高速処理を実現する場合のカギMasaki Yamakawa
 
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明MITSUNARI Shigeo
 
InnoDBのすゝめ(仮)
InnoDBのすゝめ(仮)InnoDBのすゝめ(仮)
InnoDBのすゝめ(仮)Takanori Sejima
 
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法natsumo
 

Mais procurados (20)

Ansibleの最近の動向を追ってみた
Ansibleの最近の動向を追ってみたAnsibleの最近の動向を追ってみた
Ansibleの最近の動向を追ってみた
 
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
 
Plan 9のお話
Plan 9のお話Plan 9のお話
Plan 9のお話
 
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
 
暗認本読書会5
暗認本読書会5暗認本読書会5
暗認本読書会5
 
AHVでみるCVM Autopathの仕組み
AHVでみるCVM Autopathの仕組みAHVでみるCVM Autopathの仕組み
AHVでみるCVM Autopathの仕組み
 
全域木いろいろ
全域木いろいろ全域木いろいろ
全域木いろいろ
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
 
Androidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリAndroidで使えるJSON-Javaライブラリ
Androidで使えるJSON-Javaライブラリ
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル
 
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
 
蟻本輪講 データ構造
蟻本輪講 データ構造蟻本輪講 データ構造
蟻本輪講 データ構造
 
AWSで透過プロキシをやってみた
AWSで透過プロキシをやってみたAWSで透過プロキシをやってみた
AWSで透過プロキシをやってみた
 
Apache spark 2.3 and beyond
Apache spark 2.3 and beyondApache spark 2.3 and beyond
Apache spark 2.3 and beyond
 
Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装
 
インメモリーで超高速処理を実現する場合のカギ
インメモリーで超高速処理を実現する場合のカギインメモリーで超高速処理を実現する場合のカギ
インメモリーで超高速処理を実現する場合のカギ
 
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
 
大昔のMMU
大昔のMMU大昔のMMU
大昔のMMU
 
InnoDBのすゝめ(仮)
InnoDBのすゝめ(仮)InnoDBのすゝめ(仮)
InnoDBのすゝめ(仮)
 
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法
【Swift】SDKの読み込みにuse framework!が使えない場合の対処方法
 

Semelhante a 13.並行、平行與非同步

並行與平行
並行與平行並行與平行
並行與平行Justin Lin
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJustin Lin
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJustin Lin
 
6. 非同步設計
6. 非同步設計6. 非同步設計
6. 非同步設計Justin Lin
 
執行緒與並行API
執行緒與並行API執行緒與並行API
執行緒與並行APIJustin Lin
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcipDai Jun
 
CH11:執行緒與並行API
CH11:執行緒與並行APICH11:執行緒與並行API
CH11:執行緒與並行APIJustin Lin
 

Semelhante a 13.並行、平行與非同步 (9)

並行與平行
並行與平行並行與平行
並行與平行
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
 
6. 非同步設計
6. 非同步設計6. 非同步設計
6. 非同步設計
 
執行緒與並行API
執行緒與並行API執行緒與並行API
執行緒與並行API
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcip
 
CH11:執行緒與並行API
CH11:執行緒與並行APICH11:執行緒與並行API
CH11:執行緒與並行API
 
SCJP ch15
SCJP ch15SCJP ch15
SCJP ch15
 
Chapter2
Chapter2  Chapter2
Chapter2
 

Mais de Justin Lin

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring BootJustin Lin
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityJustin Lin
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走Justin Lin
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMailJustin Lin
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Justin Lin
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫Justin Lin
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤Justin Lin
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTLJustin Lin
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSPJustin Lin
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Justin Lin
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理Justin Lin
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應Justin Lin
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletJustin Lin
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式Justin Lin
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題Justin Lin
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能Justin Lin
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組Justin Lin
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組Justin Lin
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理Justin Lin
 
6. 類別的繼承
6. 類別的繼承6. 類別的繼承
6. 類別的繼承Justin Lin
 

Mais de Justin Lin (20)

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理
 
6. 類別的繼承
6. 類別的繼承6. 類別的繼承
6. 類別的繼承
 

13.並行、平行與非同步