對非搶占式多執行緒來說,不管什麼時候只要有乙個執行緒呼叫乙個阻塞操作(blocking operation),整個程式在阻塞操作完成之前都將停止。對大部分應用程式而言,只是無法忍受的,這使得很多程式設計師離協同而去。下面我們將看到這個問題可以被有趣的解決。
require "luasocket"
host = "www.w3.org"
file = "/tr/rec-html32.html"
第三,開啟乙個tcp連線到遠端主機的80埠(http服務的標準埠)
c = assert(socket.connect(host, 80))
上面這句返回乙個連線物件,我們可以使用這個連線物件請求傳送檔案
c:send("get " .. file .. " http/1.0\r\n\r\n")
receive函式返回他送接收到的資料加上乙個表示操作狀態的字串。當主機斷開連線時,我們退出迴圈。
第四,關閉連線
end在同步接受資料的方式下,函式接收資料時不能被阻塞,而是在沒有資料可取時yield,**如下:
function receive (connection)
connection:timeout(0) -- do not block
local s, status = connection:receive(2^10)
if status == "timeout" then
coroutine.yield(connection)
endreturn s, status
end
threads = {} -- list of all live threads
function get (host, file)
-- create coroutine
local co = coroutine.create(function ()
download(host, file)
end)
-- insert it in the list
table.insert(threads, co)
end
**中table中為分配器儲存了所有活動的執行緒。
分配器**是很簡單的,它是乙個迴圈,逐個呼叫每乙個執行緒。並且從執行緒列表中移除已經完成任務的執行緒。當沒有執行緒可以執行時退出迴圈。
function dispatcher ()
while true do
local n = table.getn(threads)
if n == 0 then break end -- no more threads to run
for i=1,n do
local status, res = coroutine.resume(threads[i])
if not res then -- thread finished its task?
table.remove(threads, i)
break
endend
endend
host = "www.w3c.org"
get(host, "/tr/html401/html40.txt")
get(host, "/tr/2002/rec-xhtml1-20020801/xhtml1.pdf")
get(host, "/tr/rec-html32.html")
get(host,
"/tr/2000/rec-dom-level-2-core-20001113/dom2-core.txt")
dispatcher() -- main loop
儘管效率提高了,但距離理想的實現還相差甚遠,當至少有乙個執行緒有資料可讀取的時候,這段**可以很好的執行。否則,分配器將進入忙等待狀態,從乙個執行緒到另乙個執行緒不停的迴圈判斷是否有資料可獲取。結果協同實現的**比順序讀取將花費30倍的cpu時間。
在內層的迴圈分配器收集連線表中timeout地連線,注意:receive將連線傳遞給yield,因此resume返回他們。當所有的連線都timeout分配器呼叫select等待任一連線狀態的改變。最終的實現效率和上乙個協同實現的方式相當,另外,他不會發生忙等待,比起順序實現的方式消耗cpu的時間僅僅多一點點。
原文:lua乙個小巧指令碼語言學習筆記
lua教程非搶占式多執行緒-38
Lua非搶占式多執行緒
當乙個協同正在執行時,不能在外部終止他。只能通過顯示的呼叫 yield 掛起他的執行。對於某些應用來說這個不存在問題,但有些應用對此是不能忍受的。不存在搶占式呼叫的程式是容易編寫的。不需要考慮同步帶來的 bugs,因為程式中的所有執行緒間的同步都是顯示的。你僅僅需要在協同 超出臨界區時呼叫 yiel...
執行緒的搶占式和非搶占式排程
在乙個程序裡,執行緒的排程有搶占式或者非搶占的模式。在搶占模式下,作業系統負責分配 時間給各個程序,一旦當前的程序使用完分配給自己的 時間,作業系統將決定下乙個占用 時間的是哪乙個執行緒。因此作業系統將定期的中斷當前正在執行的執行緒,將 分配給在等待佇列的下乙個執行緒。所以任何乙個執行緒都不能獨佔 ...
執行緒的排程有搶占式或者非搶占
在乙個程序裡,執行緒的排程有搶占式或者非搶占的模式。在搶占模式下,作業系統負責分配 時間給各個程序,一旦當前的程序使用完分配給自己的 時間,作業系統將決定下乙個占用 時間的是哪乙個執行緒。因此作業系統將定期的中斷當前正在執行的執行緒,將 分配給在等待佇列的下乙個執行緒。所以任何乙個執行緒都不能獨佔 ...