2009-04-08 18 views
1

pthread_joinを使わずに別のスレッドが初期化を完了するまで、スレッドを停止したい。 私は結合を使用しようとしましたが、私たちが持っているいくつかの非同期スレッド間通信システムのためにデッドロックに繋がります。 今、私はこれを達成するために(カスタム)ロックを使用しています。スレッド1ではpthread_joinを使わずにpthread_createを終了するのを待つ

スレッド2では
lock_OfflineWorker.Lock() 
if (pthread_create(&tid0, NULL, RunOfflineWorker, NULL) != 0) 
{ 
} 

lock_OfflineWorker.TryLock(); 
lock_OfflineWorker.Unlock(); 

bool OfflineWorker::Initialize() 
{ 
    lock_OfflineWorker.Unlock(); 
} 

しかし、これは洗練されていないと私は副作用(別のデッドロックの可能性)についてあまりよく分かりません。 これはいいですか?ジョブが到達するまで待機するように忘れたあなたはpthreadの条件を使用することができます

void* RunOfflineWorker(void* pData) 
{ 
    g_OfflineWorker.Initialize(); 
} 
+0

OfflineWorkerは初期化を行い、その後他の作業を続行しますが、そうですか? – jpalecek

+0

はい。実際の関数の最後にはリターンがあります。いくつかのハートビート操作(ライブラリ関数)を実行しますが、重い操作は行いません。 – Gayan

+0

ロックされた別のスレッドからpthread mutexを(移植可能に)ロック解除することはできません。 http://opengroup.org/onlinepubs/007908775/xsh/pthread_mutex_lock.htmlを参照してください。下記のように条件変数を使用してください。 – Doug

答えて

7

「RunOfflineWorker」機能を含める: ない場合は、

EDITは(それ以外のロックまたはを使用して)これを達成するための別の方法があります希望の状態。

スレッド1はpthread_cond_wait()で待機し、スレッド2はpthread_cond_signal()でそれを通知します。

は次のものが必要です。

bool   condition ; // or anything else to be tested 
pthread_mutex_t mutex ; 
pthread_cond_t cond ; 

すべてのINIT最初のスレッド:

condition = false ; 
pthread_mutex_init(&mutex , PTHREAD_MUTEX_INITIALIZER); 
pthread_cond_init(&cond , PTHREAD_COND_INITIALIZER); 

そして、それがロックされたミューテックスで待機します。 通常、待ち状態をループに入れて、状況を確認します。適切な場合

pthread_mutex_lock(&mutex); 
while(! condition) 
{ 
    pthread_cond_wait(&cond , &mutex); 
} 
pthread_mutex_unlock(&mutex); 

他のスレッドがこの処理を行います。私はあなたのソリューションは、あなたがスレッド1に代わりlock_OfflineWorker.TryLock()lock_OfflineWorker.Lock()を使用する必要があることを除いて、ちょうど良いと思い

pthread_mutex_lock(&mutex); 
condition = true ; // or false ... 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 
+0

あなたがミューテックスに必要なコードを含むことを忘れたことを除いて – jpalecek

+0

私はpthread条件を使ってシステムを動作させました。私はwhileループを使いませんでした。ちょうど条件を待っていました。 pthread_cond_waitを呼び出す前にミューテックスをロックする必要がありますか? pthread_cond_waitは指定されたmutexを自動的にロックおよびロック解除しませんか? – Gayan

+0

私はinitを追加しました。 ループは、条件が本当に満たされているかどうかをチェックするためにスレッド2が使用する可能性があります。 pthread_cond_signal(cond); はい、pthread_cond_waitでロックを解除する前にロックする必要があります。 –

1

からTryLock()で、それが実際にdoesnの何も待たずに。ロックされた同じスレッドによって解放される必要があるため、mutexを使用することはできません。セマフォベースのロックが実行されます。モニタ(つまり、mutex + condvar)を使用すると、もっと複雑になります。

デッドロックについて:OfflineWorkerの初期化部分(つまり、ロックを解除する前のコード)がどこでも待機しないと、デッドロックは発生しません。あなたのソリューションに実際のデッドロックがある場合、スレッド1にスレッド2を待たせる他の解決策もあります(私はそのような状況を想像することができます)。

コメントの後編集:スレッド2の初期化が完了するのを待っている間にスレッド1にメッセージを渡すと、特にメッセージの境界バッファがある場合やメッセージを渡す機能返事を待つ。この状況では、スレッド2を待つという考えを放棄し、初期化が完了したときにスレッド2から呼び出されるコールバックを渡すことをお勧めします。

+0

私はコードをここでたくさん省略しました。そこにはスレッド1にメッセージを渡す関数がありますが、これらはデッドロックを引き起こしてはいけないと言っています。私はそれを調べます。ありがとうございました – Gayan

関連する問題