2011-04-20 16 views
3

Linux、Xenomai、RTAIのPREEMPT_RTパッチを私の論文のベンチマークに使うために、ExpressLogicからPOSIXでリアルタイムThread_Metricを移植しようとしています。今、私はとしてのpthreadを取るた、tm_thread_suspendとtm_thread_resume機能を実装しようとしているpthreadを入力として受け取り、中断する関数

void tm_initialize(void (*test_initialization_function)(void)); 
int tm_thread_create(int thread_id, int priority, void (*entry_function)(void)); 
int tm_thread_resume(int thread_id); 
int tm_thread_suspend(int thread_id); 
void tm_thread_relinquish(void); 
void tm_thread_sleep(int seconds); 
int tm_queue_create(int queue_id); 
int tm_queue_send(int queue_id, unsigned long *message_ptr); 
int tm_queue_receive(int queue_id, unsigned long *message_ptr); 
int tm_semaphore_create(int semaphore_id); 
int tm_semaphore_get(int semaphore_id); 
int tm_semaphore_put(int semaphore_id); 
int tm_memory_pool_create(int pool_id); 
int tm_memory_pool_allocate(int pool_id, unsigned char **memory_ptr); 
int tm_memory_pool_deallocate(int pool_id, unsigned char *memory_ptr); 

:彼らはあなたがベンチマークが動作するために実装する必要があり、以下の機能を備えたCソースファイルを、提供します入力。私はpthread_mutex_lockとpthread_cond_waitルーチンでpthreadを中断できることを知っていますが、これらをstart_functionスレッドから呼び出さなければなりません。私はこの種のもので新しく、私は頭の中でやり遂げています。どんな助けもありがとうございます。

答えて

1

pthreadの実装には、これらの機能があります。 http://www.unix.com/man-page/all/3t/pthread_suspend/しかし、あなたのLinuxカーネルはそれらをサポートしていないかもしれません。

+0

'pthread_suspend'はpthread関数ではなく、ベンダー拡張です。 –

+0

'pthread_suspend()とpthread_continue()はX/Openによって開発されました。 – bmargulies

+0

まだ標準には含まれていません。あなたはおそらく理論的な文書を掘り下げ、かなり良い理由を見つけることができます。 –

3

pthread_suspend実際に利用可能な場合は行く方法です。この解決法は、それが価値よりももっと汚いかもしれません。各スレッドについては、semaphoreを保持してください。各スレッドがシグナルをリッスンするようにします。シグナルハンドラでは、関連するセマフォに対して単にdownを実行します。

スレッドをstopにするには、信号を送信してください(おそらくリアルタイム信号を使用するのが最も良いでしょう)。ハンドラで停止します。ハンドラは、デフォルトでマスクされます(つまり、同じシグナルが受信される前に受信された場合は、再度呼び出されません)。スレッドを再起動する場合は、単にセマフォ上でupを実行します。

警告:あなたができる場合

  • 使用を示唆するもの@bmarguliesが、それは
  • より良い(より安全、クリーン、より効率的な)だあなたはまた、代わりにセマフォ
  • ディーリングのミューテックスを使用することができます信号は厄介な仕事です。確認して着手する前に、私はかなり確信してsem_wait(3) ISN午前システムコール
  • SA_RESTART
  • を中断し、再開について
    • 非同期シグナル安全
    • スレッドとシグナル
    • を読んで(再)非同期信号は安全ですが、安全である限り、は使用しませんSA_NODEFER(理由はありません)

    残念ながら、私はこれについて本当に恒例の無料のドキュメントを見つけることができません。それでも、恒星であろうとなかろうと、多くの無料の文書があります。

    @Rによって示唆されるように編集

    ..あなたが(代わりに危険なsem_waitの)を使用することができることを阻止async-signal-safeの機能があります。ここにはa list of functions you may safely useがあります。

    +0

    適切な方法がありますが、シグナルハンドラでは非同期シグナルセーフな機能が必要です。私の答えはいくつかのアイデアをスケッチしています。 –

    +0

    @R ..それは素晴らしい考えです。私は 'SUSv3'がこのアプローチの問題を解決するasync-signal-safeとして' pselect(2) 'を指定しているのを見ることができます。 – cnicutar

    1

    あなたは(非同期シグナルセーフでない機能を備えたすべての問題を回避する)2つの信号を使用して、完全に移植可能これを行うことができます。

    シグナルハンドラはアトミックに第2の信号をブロック解除し、無期限にスリープ状態にpselectを使用する「のスレッドを一時停止」。 2番目のシグナルはpselectを終了させ、シグナルハンドラをリターンさせます。

    また、async-signal-safeインターフェイスを使用する他のソリューションもたくさんあります。基本的には、ファイルディスクリプタを扱い、ユーザー空間の同期プリミティブではなくブロックするものです。たとえば、パイプからシグナルハンドラreadを取得し、パイプにシングルバイトを書き込んでスレッドを再開すると、

    0

    これを行う方法は、sigwait()とpthread_killを使用することです。

    //グローバル変数

    int _fSigSet; 
    

    のpthread_createを呼び出す前に、我々はシグナルマスクを設定します。すべてのスレッドはマスクを継承します。あなたは私が推測するスレッド関数でマスクを設定することができます。

    sigemptyset(&_fSigSet); 
    sigaddset(&_fSigSet, SIGUSR1); 
    sigaddset(&_fSigSet, SIGSEGV); 
    pthread_sigmask(SIG_BLOCK, &_fSigSet, NULL); 
    ... 
    pthread_create(&Thread, NULL, ThreadProc, NULL); 
    ... 
    

    一時停止するには:

    int nSig; // signal you get if you care. 
    sigwait(&_fSigSet, &nSig); // thread is suspended here waiting for signal. 
    

    を再開するには:

    pthread_kill(&Thread, SIGUSR1); 
    

    をあなたがいないことに注意して、いくつかの理由でSIGUSR1を使用するカント場合はここで我々が使用するコードですすべての信号が私たちのために働きます。私たちは何か間違っているかもしれませんが、SIGCONTは動作しません。

    この方法ではスレッドを一時停止していますが、このメソッドはmutexと条件変数を使用するよりも5倍高速でした。

    このテクニックを使用しているのはcodeです。

    関連する問題