2013-12-07 42 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也可以刷新,不需要再次调用它。