2013-12-07 226 views
1

Thread.h類實現了像Java中的Thread類一樣的運行方法,因此每個繼承Thread的類都會運行。C++ 11線程等待

在下面的例子中運行兩個線程:Producer和Reader,第一個(Producer)在無限循環中打印一個計數器,第二個線程(Reader)1)調用等待產生,2)寫入一些int和3)通知方法。等待使用一個condition_variable變量。

問題是「producer-> wait();」 Reader :: run方法內部不會阻止生產者並繼續寫入,有什麼不對?

g++ -std=c++11 -pthread main.cpp 

由於事先編譯

//in main.cpp 
int main() { 
    Producer p ; 
    Reader r (&p); 
    p.start(); 
    r.start(); 
    p.join(); 
    r.join(); 
    cout << "end" << endl << flush; 
} 

類:

// in main.cpp 
#include <iostream> 
#include <unistd.h> 
#include "Thread.h" 
class Producer : public Thread { 
public: 
    Producer() {i = 0;} 

    virtual void run() ; 
private: 
    int i; 
}; 
void Producer::run() { 
    while (1) { 
     usleep (1000); 
     cout << "Producer count: " << i++ << endl << flush; 
    }; 
}; 

讀取器類

// in main.cpp 
class Reader : public Thread { 
public: 
    Reader (Producer* p) {producer = p; i = 0;} 

virtual void run() ; 
private: 
    int i; 
    Producer* producer; 
}; 
void Reader::run() { 
    while (1) { 
     usleep (1000); 
     i++; 
     if (! (i % 1000)) { 
      cout << "waiting Producer" << endl << flush; 
      producer->wait(); 
      cout << "write 10000 int" << endl << flush; 
      for (int k = 0; k < 1000; k++) { 
       usleep (1000); 
       cout << "      Reader: count " << k << endl << flush; 
      } 

      producer->notify(); 
     } 
    }; 
}; 

Thread.h:

#ifndef THREAD_H_ 
#define THREAD_H_ 
#include <thread> 
#include <mutex> 
#include <condition_variable> 
using namespace std; 

class Runnable { 
public: 
    virtual void run() = 0; 
}; 

class Thread: virtual public Runnable { 
private: 
    mutex mtx; 
    condition_variable cv; 
    thread* theThread; 
    Runnable * _runnable; 
    Runnable * execRunnable; 

    static void * __run (void * cthis) { 
     static_cast<Runnable*> (cthis)->run(); 
     return nullptr; 
    } 

public: 
    Thread() : 
     _runnable (nullptr) { 
     theThread = nullptr; 
     execRunnable = this; 
    } 

    virtual ~Thread() { 
     if (theThread) { 
      theThread->detach(); 
      delete theThread; 
      theThread = nullptr; 
     } 
    } 

void wait () { 
    unique_lock<std::mutex> lk (mtx); 
    cv.wait (lk); 
} 

void notify() { 
    cv.notify_all(); 
} 

void start() { 
    if (this->_runnable != nullptr) { 
     execRunnable = this->_runnable; 
    } 

    if (theThread) { 
     delete theThread; 
    } 

    theThread = new thread (__run, execRunnable); 
} 

void join() { 
    if (theThread) { 
     theThread->join(); 
     delete theThread; 
     theThread = nullptr; 
    } 
} 

bool isJoinable() { 
    return theThread->joinable(); 
} 

void stop() { 
    if (theThread) { 
     theThread->detach(); 
     delete theThread; 
     theThread = nullptr; 
    } 
} 

}; 
#endif 

回答

1

您不能像這樣停止生產者線程。您需要從讀者線程設置一些變量並在生產者中測試其值。然後生產者可以調用wait(),並且只有在讀者調用notify()後纔會繼續。 順便說一句。 endl也可以刷新,不需要再次調用它。