2013-05-21 60 views
0

我有一個進程P和一個內核線程KT。我想同步P與KT的執行。 KT基本上是一個事件處理程序。但我的要求是KT不應該繼續處理事件,如果P正在運行。所以我需要暫停P,然後繼續在KT中進行事件處理並恢復P.因此,我的問題是,從KT開始,我該如何強制搶佔P?稍後恢復時,我可以使用wake_up_process()。如何從另一個進程/內核線程中搶佔一個進程?

對於調度進程,常用的技巧是將狀態設置爲TASK_INTERRUPTIBLE並調用schedule()。如果我保存了task_struct指針P,然後從KT開始安排P,我將P(而不是當前)的狀態設置爲TASK_INTERRUPTIBLE並調用調度?這是一個黑客,它會工作嗎?你看到我失蹤的任何干淨的方式嗎?

是否有一些信號可以發送P讓它搶佔?

+2

如果需要同步,爲什麼不使用同步原語(例如futex)而不是一些晦澀的技巧?在需要處理的時候阻止進程並將其喚醒。 – Damon

+0

'SIGSTOP'(因爲你問的信號)是相似的 - 爲什麼應用這種黑客?使用多個線程意味着並行性(否則它並沒有太大的意義 - 如果線程只能獨佔運行,那麼也可以使用單個線程來處理所有事情)。所以,讓消費線程(應用程序)阻塞在futex或eventfd上(如果你喜歡,可以通過epoll),而生產者(內核線程)在有需要時做出通知。它也不太容易失敗。 – Damon

+0

謝謝達蒙。我重新設計使用鎖而不是黑客。 – spa

回答

1

你不能做你在問什麼。當然你可以設置狀態爲TASK_INTERRUPTIBLE從另一個進程/線程運行在相同或不同的CPU /內核上。但是你不能在另一個CPU /內核上調用schedule()(出於同樣的原因,你不能在另一個CPU /內核上調用任何其他功能)。考慮到schedule()不會將CPU /內核ID作爲參數,那麼如何告訴它,core1應該重新計劃?

這些類型的同步要求的另一種流行解決方案是使用實時優先級。這幾乎和你提出的一樣醜陋,但如果你的內核支持實時優先級,它實際上可以工作。這裏的想法很簡單,過程P比KT具有更高的優先級,並且它會在KT準備好運行時搶佔KT。使用CPU親和力將兩個進程強制到相同的CPU /內核上(這很重要,否則無法工作!)。順便說一下,在這種方法中沒有任何真正的同步 - 當P和KT彼此相對運行時,您嚴格依賴RT優先級來強制執行。

我建議你接受Damon的建議並重新設計,因爲沒有真正乾淨的方式來做你想問的問題,但是有許多幹淨的方法來同步兩個過程。

+1

如果你不能遠程喚醒一個等待事件的線程,這意味着一個線程離開一個被另一個線程等待的互斥體,不能喚醒等待的線程,但肯定會發生(而且等待的線程不會「等待下一個計時器開始執行)。那麼這工作怎麼可能呢? – BeeOnRope

+0

@BeeOnRope - 你不能使用互斥信號發送一個事件(參見[這裏](https://stackoverflow.com/questions/12551341/when-is-a-condition-variable-needed-isnt-a-mutex -enough/12569318#12569318))但您可以使用包含互斥鎖的條件變量,但也使用信號燈式事件通知。而且,是的,你可以遠程喚醒一個線程,但通過互斥量,信號量和條件變量,它不是**你正在調度線程,內核是_!使用線程狀態和內核調度原語進行線程同步註定會失敗。這是我的觀點。 – slowjelj

+0

我的意思是一個核心上的代碼在所有的時間觸發另一個核心上的代碼。例如,當一個線程離開一個「互斥體」,而另一個線程正在等待該互斥體時,該「其他線程」通常將開始在_another_ core上運行(因爲剛剛離開該互斥體的代碼仍在其核心中運行)。我不知道你爲什麼指的是事件或條件變量:我只是選擇互斥量作爲併發控制對象的最簡單的例子,這同樣適用於信號量,障礙,條件變量。 – BeeOnRope

相關問題