簡體   English   中英

如何實現僅在一個線程中運行的幾個“線程”

[英]How to implement several 'threads' running in only one thread

最近我一直在想:他們如何只在一個線程中實現幾個'線程'?

我的意思是,他們如何只在一個線程中實現幾個並行運行的代碼? 他們如何保存'線程'的狀態,創建一個中斷並將CPU傳遞給下一個?

我認為Scala-actors實現了這一點。 但是怎么樣?

這可以回答JVM或C,沒關系。 我真的很想學習它的理論。

我認為你在這里混淆了協程綠線

協同程序在准備好的時候放棄控制,沒有任何中斷,所以關於中斷的問題在這里是無關緊要的。 Scala actor被實現為協同程序。

綠色線程是由虛擬機實現的用戶模式線程,不使用本機OS功能。 顯然,虛擬機可以將任何指令插入正在執行的代碼中,以檢查是否需要切換到另一個線程。

使用actor很簡單,而不是每個actor使用一個線程,而是使用相同的線程為多個actor執行消息。 但是,如果actor執行阻塞調用或繁重計算,則必須使用另一個線程來執行其他actor中的消息。

綠色線程是輕量級線程,可以在VM級別實現。 綠色線程始終映射到一個或多個OS線程。 VM在用戶空間中處理同步和線程切換,這可以顯着減少開銷。 但是,綠色線程存在缺陷,例如IO調用可能導致線程阻塞,然后VM無法“重用”OS線程用於另一個綠色線程,而必須使用額外的OS線程。

另一種解決方案是使用在Scala編譯器中實現的continuation。 然后,在JVM字節碼級別處理執行的中斷和恢復,其中保存和恢復本地狀態。 無需VM支持。

你的意思是像Java中的ExecutorService或ScheduledExecutorService中的任務嗎?

這些任務將添加到隊列中並執行完成。 當一個完成另一個開始。 如果您有一個延遲循環,則可以使用重復的計划任務。 它為每次迭代完成,並允許其他任務運行。

如果您想了解更多詳細信息,您可能會發現閱讀有趣的代碼。

使用協同程序

Akka庫是一個非常好的actor模型實現。 它有一個非常好的直接Java API(除了Scala之外),而且文檔非常好

一種方法是讓用戶代碼中的線程包自己注冊來自內核的某種定時器中斷。 每當它收到這樣的中斷時,它就會告訴內核停止執行本身運行多個不同線程的所有內核線程。 對於每個線程,定時器中斷代碼可以檢查堆棧中的那些線程,在輔助位置記錄重要信息(寄存器,堆棧指針,程序計數器等),然后加載存儲的信息中的另一個模擬在該實際線程上運行的線程。 然后它可以恢復運行模擬線程的內核線程。 通過這種方式,您可以模擬在單個內核線程上運行的多個線程之間的上下文切換。

要實現鎖定等功能,您可以在用戶空間中本地跟蹤所有鎖定信息。 每當模擬線程嘗試獲取鎖時,您都可以檢查線程是否可以成功獲取鎖。 如果是這樣,你只需給它鎖。 否則,您通過交換該真實線程上運行的模擬線程來模擬上下文切換,然后將模擬線程標記為阻塞,直到鎖再次釋放為止。

這只是一個開始 - 這里有很多其他細節(如果其中一個模擬線程試圖阻塞I / O操作怎么辦?你不能只阻止內核線程,因為這會停止所有模擬線程! ),但這是這個想法的要點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM