多核處理器越來越普及,那有沒有一種簡單的辦法,能夠讓我們寫的軟件釋放多核的威力?答案是:Yes。隨著Golang, Erlang, Scale等為并發(fā)設計的程序語言的興起,新的并發(fā)模式逐漸清晰。正如過程式編程和面向對象一樣,一個好的編程模式需要有一個極其簡潔的內核,還有在此之 上豐富的外延,可以解決現(xiàn)實世界中各種各樣的問題。本文以GO語言為例,解釋其中內核、外延。
并發(fā)模式之內核
這種并發(fā)模式的內核只需要協(xié)程和通道就夠了。其中協(xié)程負責執(zhí)行代碼,通道負責在協(xié)程之間傳遞事件。
并發(fā)編程一直以來都是個非常困難的工作。要想編寫一個良好的并發(fā)程序,我們不得不了解線程, 鎖,semaphore,barrier甚至CPU更新高速緩存的方式,而且他們個個都有怪脾氣,處處是陷阱。筆者除非萬不得以,決不會自己操作這些底層 并發(fā)元素。一個簡潔的并發(fā)模式不需要這些復雜的底層元素,只需協(xié)程和通道就夠了。
協(xié)程是輕量級的線程。在過程式編程中,當調用一個過程的時候,需要等待其執(zhí)行完才返回。而調用一個協(xié)程的時候,不需要等待其執(zhí)行完,會立即返回。協(xié)程十分 輕量,Go語言可以在一個進程中執(zhí)行有數(shù)以十萬計的協(xié)程,依舊保持高性能。而對于普通的平臺,一個進程有數(shù)千個線程,其CPU會忙于上下文切換,性能急劇 下降。隨意創(chuàng)建線程可不是一個好主意,但是我們可以大量使用的協(xié)程。
通道是協(xié)程之間的數(shù)據(jù)傳輸通道。通道可以在眾多的協(xié)程之間傳遞數(shù)據(jù),具體可以值也可以是個引用。通道有兩種使用方式。
· 協(xié)程可以試圖向通道放入數(shù)據(jù),如果通道滿了,會掛起協(xié)程,直到通道可以為他放入數(shù)據(jù)為止。
· 協(xié)程可以試圖向通道索取數(shù)據(jù),如果通道沒有數(shù)據(jù),會掛起協(xié)程,直到通道返回數(shù)據(jù)為止。
如此,通道就可以在傳遞數(shù)據(jù)的同時,控制協(xié)程的運行。有點像事件驅動,也有點像阻塞隊列。這兩個概念非常的簡單,各個語言平臺都會有相應的實現(xiàn)。在Java和C上也各有庫可以實現(xiàn)兩者。
只要有協(xié)程和通道,就可以優(yōu)雅的解決并發(fā)的問題。不必使用其他和并發(fā)有關的概念。那如何用這兩把利刃解決各式各樣的實際問題呢?