基于无锁队列和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