多對一模型(many-to-one model)
想像一整組工人把他們所有的電話都集中透過辦公室裡共用的一條電話線打出去。他們可以輪流,感覺像一支忙碌的團隊,但任何一刻其實只有一通電話真正接通,而且如果那條線被掛在等候中卡住了,其他人也都打不出去。多對一模型就是執行緒的這種安排:許多使用者層級執行緒全部對映到單一一條核心執行緒上。程式感覺像多執行緒,但核心只看到一條可排程的線路。
具體來說,在多對一裡,使用者空間的函式庫管理許多執行緒,而作業系統只給這個行程一條核心執行緒。在這些使用者執行緒之間切換完全發生在使用者空間,又快又便宜。但因為底下只有一條核心執行緒,這些執行緒共用通往 CPU 的單一連線。執行緒管理(建立、切換、排程)很有效率,因為一般的切換從不進入核心。
兩個弱點是決定性的,而且直接源自那唯一一條核心執行緒。第一,如果任何一條使用者執行緒發出會阻塞的系統呼叫,整個行程都會阻塞,因為核心把它唯一的執行緒停住了,沒有別的可以替這個行程跑。第二,由於這個行程只握有一條核心執行緒,它一次只能在一個 CPU 核心上執行,所以即使在八核心機器上,多對一執行緒也永遠達不到真正的平行。這就是為什麼這個模型在通用用途上大致被棄用;它主要存活在純使用者層級執行緒與輕量綠色執行緒函式庫中,那些地方可以接受這些限制。
早期某個 Java 實作以多對一的方式使用綠色執行緒:你可以建立許多執行緒,但它們全擠在一條核心執行緒上,所以一個 Java 程式無法用到第二個 CPU 核心,而一條執行緒在等輸入而阻塞就可能拖住其餘。後來 Java 改用一對一模型,正是為了修正這一點。
許多使用者執行緒、一條核心執行緒,沒有平行,而且一次阻塞就讓全部凍結。
多對一永遠用不到一個以上的核心,而且單一一個會阻塞的系統呼叫就會讓整個行程停住。它唯一的優點是切換不進核心因而便宜。