基于无锁队列和c++11的高性能线程池--------代码写的非常规范(多读多写并发的无锁队列)

基于无锁队列和c++11的高性能线程池
线程使用c++11库
和线程池之间的消息通讯使用一个简单的无锁消息队列
适用于linux平台,gcc 4.6以上
标签: <无> 代码片段(6) [全屏查看所有代码]
1. [代码]lckfree.h     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 // lckfree.h 

02 // Implementation of lock free queue using CAS operations 

03 // for simple multi-threading use cases like: 

04 // 1. multiple worker to process incoming messages 

05 // 2. async processing using a thread pool 

06 // 3. simple tcp server deal with async requests 

07 // Author: typhoon_1986@163.com 

08 // Refrence: http://coolshell.cn/articles/8239.html 

09   

10 #ifndef __LCKFREE_H__ 

11 #define __LCKFREE_H__ 

12   

13 #include <string> 

14 using namespace std; 

15   

16 namespace bfd { 

17   

18 struct LinkNode { 

19   string data; 

20   LinkNode* next; 

21 }; 

22 typedef struct LinkNode LinkNode; 

23   

24 class LckFreeQueue { 

25  public: 

26   LckFreeQueue(); 

27   ~LckFreeQueue(); 

28   

29   int push(const string &msg); 

30   string pop();  // non-block pop method 

31 //  string bpop(); // block pop method 

32   bool empty(); 

33  private: 

34   LinkNode * head_; 

35   LinkNode * tail_; 

36   bool empty_; 

37   unsigned int length_; 

38 }; 

39   

40 } // namespace bfd 

41 #endif
2. [代码]lckfree.cpp     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 #include <lckfree.h> 

02   

03 namespace bfd { 

04   

05 LckFreeQueue::LckFreeQueue(): head_(NULL), tail_(NULL), empty_(true), length_(0) { 

06   head_ = new LinkNode; 

07   head_->next = NULL; 

08   tail_ = head_; 

09 } 

10   

11 LckFreeQueue::~LckFreeQueue() { 

12   LinkNode *p = head_; 

13   if (p) { 

14     LinkNode *q = p->next; 

15     delete p; 

16     p = q; 

17   } 

18 } 

19   

20 int LckFreeQueue::push(const string &msg) { 

21   LinkNode * q = new LinkNode; 

22   q->data = msg; 

23   q->next = NULL; 

24   

25   LinkNode * p = tail_; 

26   LinkNode * oldp = p; 

27   do { 

28     while (p->next != NULL) 

29         p = p->next; 

30   } while( __sync_bool_compare_and_swap(&(p->next), NULL, q) != true); //如果没有把结点链在尾上,再试 

31   

32   __sync_bool_compare_and_swap(&tail_, oldp, q); //置尾结点 

33   return 0; 

34 } 

35   

36 string LckFreeQueue::pop() { 

37   LinkNode * p; 

38   do{ 

39     p = head_; 

40     if (p->next == NULL){ 

41       return ""; 

42     } 

43   } while( __sync_bool_compare_and_swap(&head_, p, p->next) != true ); 

44   return p->next->data; 

45 } 

46   

47 bool LckFreeQueue::empty() { 

48   return empty_; 

49 } 

50   

51 }
3. [代码]workthreadpool.h     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 // workthreadpool.h 

02 // 一个用于将消息分发给多个进程,并使用多个进程处理的库,工作进程并不返回数据 

03 #ifndef __WORK_THREAD_POOL__ 

04 #define __WORK_THREAD_POOL__ 

05   

06 #include <stdio.h> 

07 #include <thread> 

08 #include <queue> 

09 #include <string> 

10 #include <vector> 

11 #include "lckfree.h" 

12   

13 using namespace std; 

14 namespace bfd { 

15   

16 class WorkThreadPool { 

17  public: 

18   WorkThreadPool(int size); 

19   virtual ~WorkThreadPool(); 

20   

21   // 需要子类继承并实现的函数,每个线程实际执行的内容 

22   virtual void Init() {}; 

23   virtual void Finish() {}; 

24   virtual void Handle(const string &msg)=0; 

25   

26   // 将消息放入处理队列, 消息只支持string类型 

27   int SendMessage(const string &msg); 

28   

29   int Start(); 

30   int Stop(); 

31   

32  private: 

33   void Worker(); 

34   

35   int size_; 

36   LckFreeQueue msg_queue_; // 线程池的协作基于这个无锁队列 

37   vector<thread> thread_pool_; 

38 }; 

39 } // namespace 

40 #endif
4. [代码]workthreadpool.cpp     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 #include "workthreadpool.h" 

02 #include <sstream> 

03 #include <unistd.h> 

04   

05 namespace bfd { 

06 WorkThreadPool::WorkThreadPool(int size) { 

07   if (size <= 0) { // 最小也需要有1个线程 

08     size_ = 1; 

09   } else { 

10     size_ = size; 

11   } 

12 } 

13   

14 WorkThreadPool::~WorkThreadPool() { 

15   

16 } 

17   

18 int WorkThreadPool::SendMessage(const string &msg) { 

19   msg_queue_.push(msg); 

20   return 0; 

21 } 

22   

23 void WorkThreadPool::Worker() { 

24   unsigned int msg_count = 0; 

25   while (1) { 

26     string msg = msg_queue_.pop(); 

27     if (msg.empty()) { 

28       printf("no msg got, sleep for 0.1 sec\n"); 

29       usleep(100000); // 0.1 sec 

30       continue; 

31     } 

32   

33     if (msg == "__exit__") { 

34       stringstream ss; 

35       ss << "exit worker: " << std::this_thread::get_id() << ", processed: " << msg_count << ".."; 

36       printf("%s\n", ss.str().c_str()); 

37       return; 

38     } 

39     Handle(msg); 

40     msg_count++; 

41     if (msg_count % 1000 == 0) { 

42       printf("every 1000 msg count\n"); 

43     } 

44   } 

45 } 

46   

47 int WorkThreadPool::Start() { 

48   for (int i=0; i < size_; i++) { 

49     thread_pool_.push_back( thread(&WorkThreadPool::Worker, this) ); 

50   } 

51   return 0; 

52 } 

53   

54 int WorkThreadPool::Stop() { 

55   for (int i=0; i < size_; i++) { 

56     SendMessage("__exit__"); 

57   } 

58   for (int i=0; i < size_; i++) { 

59     thread_pool_[i].join(); 

60   } 

61   return 0; 

62 } 

63   

64 }
5. [代码]main.cpp     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 #include "workthreadpool.h" 

02 #include <sstream> 

03 #include <math.h> 

04   

05 class MyThreadPool : public bfd::WorkThreadPool { 

06  public: 

07   MyThreadPool(int size) : bfd::WorkThreadPool(size) { 

08   } 

09   void Handle(const string &msg) { 

10     stringstream ss; 

11     ss << "worker (" << std::this_thread::get_id() << ") got msg: " << msg; 

12     printf("%s\n", ss.str().c_str()); 

13     for (int i=0; i<=999999; i++) { 

14       double result = sqrt(sqrt(i) / 93.234); 

15     } 

16   } 

17 }; 

18   

19 int main() { 

20   printf("start running ....\n"); 

21   MyThreadPool pool(5); 

22   pool.Start(); 

23   for (int i=0; i<100; i++) { 

24     pool.SendMessage("msg info ----------"); 

25   } 

26   pool.Stop(); 

27   

28   return 0; 

29 }
6. [代码]Makefile     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]
view sourceprint?
01 LIB_SRC_FILES = src/workthreadpool.cpp src/lckfree.cpp 

02 TEST_SRC_FILES = src/main.cpp 

03 INCLUDE_DIR = src 

04 STD_FLAG = -std=c++0x  

05   

06 all: main.o libs 

07     g++ $(STD_FLAG) -o test_workthreadpool main.o libworkthreadpool.so -lpthread 

08       

09 main.o: $(TEST_SRC_FILES) 

10     g++ $(STD_FLAG) -c $(TEST_SRC_FILES) -I$(INCLUDE_DIR) 

11   

12 libs: $(LIB_SRC_FILES) 

13     g++ $(STD_FLAG) -o libworkthreadpool.so -fPIC -O2 -shared -Wl,--no-as-needed -Isrc $(LIB_SRC_FILES) -lpthread 

14   

15 .PHONY : clean 

16 clean : 

17     rm -f test_workthreadpool main.o libworkthreadpool.so

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值