多线程基础(单读、单写、循环队列、无锁、lockfree)

有了前面线程创建和循环队列的基础,我们再来看一个单度、单写利用循环队列的例子,代码如下:

#include 
#include 
#include 
#include "circular_queue.h"
class ThreadBase {
 public:
  virtual ~ThreadBase() {}
  void SetMessage(const char* message) {
    message_ = message;
  }
  void Start() {
    pthread_create(&thread_id_, NULL, Hook, this);
  }
  void* Join() {
    void* ret = NULL;
    pthread_join(thread_id_, &ret);
    return ret;
  }
  virtual void Run() {
    printf("%s\n", message_.c_str());
  }
 private:
  static void* Hook(void* object) {
    ThreadBase* thread_base= static_cast(object);
    thread_base->Run();
  }
  pthread_t thread_id_;
  std::string message_;
};
class ThreadReader : public ThreadBase {
 public:
  ThreadReader(CircularQueue* queue) : queue_(queue), write_finish_(false) {}
  virtual void Run() {
    int element;
    while (!write_finish_) {
      if (queue_->Pop(&element)) {
        printf("read:%d\n",element);
      }
    }
    while (queue_->Pop(&element)) {
      printf("read:%d\n", element);
    }
  }
  void NotifyWriteFinish() {
    write_finish_ = true;
  }
 private:
  CircularQueue* queue_;
  bool write_finish_;
};

class ThreadWriter : public ThreadBase {
 public:
  ThreadWriter(CircularQueue* queue, ThreadReader* reader) : queue_(queue), reader_(reader) {}
  virtual void Run() {
    int index = 0;
    while(index < 10000) {
      if (queue_->Push(index)) {
        index++;
      }
    }
    reader_->NotifyWriteFinish();
  }
 private:
  CircularQueue* queue_;
  ThreadReader* reader_;
};
int main(int argc, char** argv) {
  CircularQueue queue(100);
  ThreadReader reader(&queue);
  ThreadWriter writer(&queue, &reader);
  reader.Start();
  writer.Start();
  reader.Join();
  writer.Join();
}

写线程不间断写入数据,写入完成后会通知读线程已经写完,读线程持续读取数据,如果得到通知后,将缓冲区中的数据再全部读出后,退出。

参考文献:

《编程之美》中1.10 双线程高效下载,但编程之美中使用了semaphore,本例子不需要使用semaphore,效率更好。

《系统程序员成长计划》4.5无锁数据结构

你可能感兴趣的:(程序设计)