2010-11-28 54 views

回答

15

如果你真的想做一些像ucontext.h函數允許的東西,我會繼續使用它們。其他任何東西都不會輕便。在POSIX中標記它們過時似乎是委員會某人的一段可怕的犯罪錯誤。 POSIX本身要求函數指針和數據指針的大小相同,並且要表示的函數指針可以表示爲void *,而C本身需要在函數指針類型之間進行轉換並返回爲往返安全,所以這個問題有很多方法本來可以解決的。

還有一個現實的問題,即轉換int argc, ...傳遞到makecontext成的形式傳遞給函數不能沒有重大援助編譯器來完成,除非可變參數和非參數可變型函數的調用約定恰好是相同的(即便如此,它是否可以做得很好也是個疑問)。然而,這個問題可以通過簡單地使用除makecontext(ucp, func, 1, (void *)arg);以外的任何形式的makecontext來解決。

也許一個更好的問題是,爲什麼你認爲ucontext.h函數是處理線程的最好方法。如果你確實想和他們一起去,我可能會建議你寫一個包裝界面,你可以用或者ucontext.h與pthreads,然後比較性能和膨脹。這也有一個好處,就是如果未來的系統不支持ucontext.h,你可以簡單地切換到基於pthread的實現編譯,一切都將簡單地工作。 (屆時,膨脹可能是不太重要的,多核的好處/ SMP將可能是巨大的,並希望並行線程的實現會越來越臃腫。)

編輯(基於OP的要求):爲貫徹落實用pthreads「合作式線程」,你需要條件變量。這裏有一個體面的並行線程的信息教您如何使用它們:

https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables

你的協作多任務處理原始的「手斷執行線程X」會去是這樣的:

self->flag = 0; 
other_thread->flag = 1; 
pthread_mutex_lock(other_thread->mutex); 
pthread_cond_signal(other_thread->cond); 
pthread_mutex_unlock(other_thread->mutex); 
pthread_mutex_lock(self->mutex); 
while (!self->flag) 
    pthread_cond_wait(self->cond, self->mutex); 
pthread_mutex_unlock(self->mutex); 

希望我得到的所有對;至少總體思路是正確的。如果有人看到錯誤,請發表評論,以便我可以修復它。有一半的鎖(other_thread的互斥鎖)對於這種用法可能完全沒有必要,所以您可以將互斥鎖作爲task_switch函數中的局部變量。你真正在做的是使用pthread_cond_waitpthread_cond_signal作爲「去睡覺」和「喚醒其他線程」原語。

4

不,沒有標準的替代品。

你選擇是

  • 繼續使用<ucontext.h>即使它們包含過時C.
  • 切換到並行線程
  • 寫自己的合作線程庫
  • 使用現有的(也可能不-so-portable)共線程庫,例如http://swtch.com/libtask/,儘管許多這樣的庫在ucontext.h之上實現
+0

我不知道如果這些不那麼便攜庫可以被移植到使用並行線程,而不是OS /機專用黑客,類似於我的答案的方法... – 2010-11-28 22:55:12

+1

可能,但是這是一個很多重量級的。 – nos 2010-11-29 08:39:23

+0

我不會說「很多」。上下文切換的幾千個週期(或者更少的SMP /多內核),以及每個線程幾十kb的額外數量(我猜在內核空間中會有2-4個頁面,而在用戶空間中會有相同的數量)。 – 2010-12-03 00:17:24

0

Open Group基本規格第6期 IEEE Std 1003.1,2004版

仍然列出makecontext()和swapcontext()具有相同的不贊成使用的語法。我還沒有看到任何更近的。

10

對於它的價值,有一個Boost.Context庫是recently accepted,只需要合併到一個官方的Boost版本。 Boost.Context解決了與POSIX ucontext系列相同的用例:低開銷合作上下文切換。作者爲性能問題付出了沉重的代價。

相關問題