2017-06-25 8 views
0

私はそれをテストするための簡単な実験をした:"pthread_cond_wait"はメインスレッドがスリープ状態になるのを待たずに、なぜですか?

  1. メインスレッドのサブスレッドを作成します。
  2. サブスレッドは条件変数を通知するためにメインスレッドを待機します。
  3. メインスレッドは3秒間スリープし、 "cond"を通知します。それからサブスレッドが "cond_wait"から目を覚まして印刷することを期待します。

コード:

#include <pthread.h> 
#include <unistd.h> 
#include <cassert> 
#include <iostream> 

using namespace std; 
pthread_mutex_t mt; 
pthread_cond_t cond; 
pthread_t tid; 
void* tf(void*arg){ 
    pthread_mutex_lock(&mt); 
    pthread_cond_wait(&cond, &mt); 
    cout<<"After main thread sleeps 3 seconds\n"; 
    return NULL; 
} 
int main(){ 
    assert(0==pthread_mutex_init(&mt,NULL)); 
    pthread_create(&tid,NULL,tf,NULL); 
    sleep(3); 
    pthread_cond_signal(&cond); 
    pthread_join(tid,NULL);//Is 2nd parameter useful? 
    pthread_cond_destroy(&cond); 
    return 0; 
} 

しかし、一度 "メインスレッドは3秒スリープした後、" 実際には、サブスレッドが印刷されます。どこが間違っていたのですか?

ありがとうございました。

答えて

3

最も重要なのは、この質問にC++タグを添付しているため、pthreadライブラリではなくC++スレッド機能を使用することです。 std::threadは、クロスプラットフォームとなるように設計されており、pthread()ライブラリのCインターフェイスを使用している煩わしさから解放されています。

次に、変数を初期化します、CとCのAPIはそれほど迷惑です。第三に、あなたが例えば、スプリアスウェイクアップを占め条件変数待ちの周りにwhileループを入れ、それを実際の条件を添付する必要が

while (not_signalled) { 
    pthread_cond_wait(&cond, &mt); 
} 

何が起こっされる可能性がありますが、あなたのスレッドが誤って目が覚めてしまうことですし、あなたが偽のウェイクアップ


ワーキングC++コード

#include <thread> 
#include <iostream> 
#include <chrono> 

using std::cout; 
using std::endl; 

std::mutex mtx; 
std::condition_variable cv; 
bool has_signalled{false}; 

void th_function() { 
    // acquire the lock 
    auto lck = std::unique_lock<std::mutex>{mtx}; 

    // loop to protect against spurious wakeups 
    while (!has_signalled) { 
     // sleep 
     cv.wait(lck); 
    } 

    cout << "Thread has been signalled" << endl; 
} 

int main() { 
    auto th = std::thread{th_function}; 

    // sleep for 2 seconds 
    std::this_thread::sleep_for(std::chrono::seconds(2)); 

    // signal and change the variable 
    { 
     std::lock_guard<std::mutex> lck{mtx}; 
     has_signalled = true; 
    } 

    // signal 
    cv.notify_one(); 

    th.join(); 
} 
から保護whileループを持っていないので、その後、終了
1

私はLinuxのスレッド機能については知らないけど、WindowsではLinuxのpthread_cond_t condに対応する変数を初期化する必要があります。

ちょうどそのように思われるpthread_cond_initという名前の関数のマンページがあります。

関連する問題