Просмотр исходного кода

fix some bugs, still have some bugs

tanghai 15 лет назад
Родитель
Сommit
29cc9d1c6f
3 измененных файлов с 54 добавлено и 33 удалено
  1. 33 15
      src/thread/thread_pool.cc
  2. 3 3
      src/thread/thread_pool.h
  3. 18 15
      src/thread/thread_pool_test.cc

+ 33 - 15
src/thread/thread_pool.cc

@@ -1,16 +1,15 @@
 #include <boost/foreach.hpp>
+#include <glog/logging.h>
 #include "thread/thread_pool.h"
 
 namespace hainan
 {
 	ThreadPool::ThreadPool():
-			num(0), work_num(0),
-			running(false)
+			num(0), running(false), work_num(0)
 	{
 	}
 	ThreadPool::~ThreadPool()
 	{
-		Stop();
 	}
 
 	void ThreadPool::Start()
@@ -27,46 +26,65 @@ namespace hainan
 
 	void ThreadPool::Stop()
 	{
+		VLOG(2) << "Stop";
 		mutex::scoped_lock lock(mtx);
 		running = false;
 		cond.notify_all();
-		while(work_num != 0)
+		while(work_num > 0)
 		{
+			VLOG(2) << "done tasks size = " << tasks.size();
 			done.wait(lock);
 		}
 	}
 
 	void ThreadPool::Loop()
 	{
-		while(running)
+		VLOG(2) << "thread start";
+		bool continued = true;
+		while(continued)
 		{
-			function<void (void)> task;
+			function<void (void)> task(0);
 			{
 				mutex::scoped_lock lock(mtx);
-				while(tasks.empty())
+				if(running && tasks.empty())
 				{
 					cond.wait(lock);
+					VLOG(2) << "get cond";
 				}
-				task = tasks.front();
-				tasks.pop_front();
-				cond.notify_one();
+
+				if(!tasks.empty())
+				{
+					VLOG(2) << "fetch task";
+					task = tasks.front();
+					tasks.pop_front();
+				}
+				continued = running || !tasks.empty();
+				VLOG(2) << "running = " << running;
+			}
+
+			if(task)
+			{
+				task();
 			}
-			task();
 		}
 		if(__sync_sub_and_fetch(&work_num, 1) == 0)
 		{
+			VLOG(2) << "work_num = " << work_num;
 			done.notify_one();
 		}
 	}
 
 	bool ThreadPool::PushTask(function<void (void)> task)
 	{
-		mutex::scoped_lock lock(mtx);
-		if(!running)
+		VLOG(2) << "push task";
 		{
-			return false;
+			mutex::scoped_lock lock(mtx);
+			if(!running)
+			{
+				return false;
+			}
+			tasks.push_back(task);
 		}
-		tasks.push_back(task);
 		cond.notify_one();
 		return true;
 	}

+ 3 - 3
src/thread/thread_pool.h

@@ -15,8 +15,8 @@ namespace hainan
 	class ThreadPool
 	{
 	private:
-		int32_t num;
-		volatile int32_t work_num;
+		int num;
+		volatile int work_num;
 		volatile bool running;
 		mutex mtx;
 		condition_variable cond;
@@ -33,7 +33,7 @@ namespace hainan
 		~ThreadPool();
 		void Start();
 		void Stop();
-		void SetNum(int32_t n);
+		void SetNum(int n);
 		bool PushTask(function<void(void)> task);
 	};
 }

+ 18 - 15
src/thread/thread_pool_test.cc

@@ -11,7 +11,7 @@ namespace hainan
 	{
 		void SetUp()
 		{
-			thread_pool.SetNum(4);
+			thread_pool.SetNum(2);
 			thread_pool.Start();
 		}
 		void TearDown()
@@ -19,30 +19,33 @@ namespace hainan
 		}
 	protected:
 		ThreadPool thread_pool;
-		boost::function<int(int)> func;
 	public:
+		ThreadPoolTest(): thread_pool()
+		{
+		}
 		void Max(int a, int b, int* z)
 		{
-			LOG(INFO) << a << " " << b;
 			*z = a > b? a : b;
 		}
 	};
 
 	TEST_F(ThreadPoolTest, Test1)
 	{
-		int x = 5;
-		int y = 6;
-		int z = 0;
-		int a = 7;
-		int b = 8;
-		int c = 0;
-		thread_pool.PushTask(
-				boost::bind(&ThreadPoolTest::Max, boost::ref(*this), x, y, &z));
-		thread_pool.PushTask(
-				boost::bind(&ThreadPoolTest::Max, boost::ref(*this), a, b, &c));
+		vector<int> x(100, 8);
+		vector<int> y(100, 9);
+		vector<int> z(100, 0);
+
+		for(int i = 0; i < 100; ++i)
+		{
+			thread_pool.PushTask(
+				boost::bind(&ThreadPoolTest::Max,
+					boost::ref(*this), x[i], y[i], &z[i]));
+		}
 		thread_pool.Stop();
-		ASSERT_EQ(6, z);
-		ASSERT_EQ(8, c);
+		for(int i = 0; i < 100; ++i)
+		{
+			ASSERT_EQ(9, z[i]) << "i = " << i;
+		}
 	}
 }