Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subsitute std for boost #36

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions thread/ThreadPool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,31 @@ void ThreadPool::start(int numThreads)

void ThreadPool::stop()
{
running_ = false;
printf("starting to stop the pool.\n");
{
MutexLockGuard lock(mutex_);
running_ = false;
}
cond_.notifyAll();
for_each(threads_.begin(),
threads_.end(),
boost::bind(&muduo::Thread::join, _1));
threads_.clear();
printf("stop the pool successfully.\n");
}

void ThreadPool::run(const Task& task)
{
if (threads_.empty())
{
task();
return;
}
else
{
MutexLockGuard lock(mutex_);
queue_.push_back(task);
cond_.notify();
}
cond_.notify();
}

ThreadPool::Task ThreadPool::take()
Expand Down Expand Up @@ -117,3 +123,33 @@ void ThreadPool::runInThread()
}
}



// // bind cores
// const int targetCore = bindcores_[i];
// cpu_set_t cpuset;
// CPU_ZERO(&cpuset);
// CPU_SET(targetCore, &cpuset);
// int ret = pthread_setaffinity_np(thread_[i], sizeof(cpu_set_t), &cpuset); // or std::thread::native_handle()
// // or pthread_self()
// if (ret != 0)
// {
// printf("[ThreadPool] thread %zu bind core %d failed\n", i, targetCore);
// }
// else
// {
// printf("[ThreadPool] thread %zu bind core %d success\n", i, targetCore);
// }

// // 线程优先级
// sched_param sp;
// sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
// ret = pthread_setschedparam(thread_[i], SCHED_FIFO, &sp);
// if (ret != 0)
// {
// printf("[ThreadPool] thread %zu set priority %d failed\n", i, sp.sched_priority);
// }
// else
// {
// printf("[ThreadPool] thread %zu set priority %d success\n", i, sp.sched_priority);
// }
21 changes: 21 additions & 0 deletions thread/ThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <boost/ptr_container/ptr_vector.hpp>

#include <deque>
#include <future>

namespace muduo
{
Expand All @@ -34,6 +35,26 @@ class ThreadPool : boost::noncopyable

void run(const Task& f);

template<typename Func, typename... Args>
inline auto run_future(Func&& func, Args&&... args) -> std::future<typename std::result_of<Func(Args...)>::type>
{
if (threads_.empty()) {
func(args...);
}
using ret_type = typename std::result_of<Func(Args...)>::type;
auto task = std::make_shared<std::packaged_task<ret_type()>>(std::bind(std::forward<Func>(func), std::forward<Args>(args)...));
auto ret = task->get_future();
do {
MutexLockGuard lock(mutex_);
if (!running_) {
throw std::runtime_error("enqueue on stopped ThreadPool");
}
queue_.push_back([task]() { (*task)(); });
} while (0);
cond_.notify();
return std::move(ret);
}

private:
void runInThread();
Task take();
Expand Down
276 changes: 276 additions & 0 deletions thread/test/Factory_cpp20.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
#include <map>

#include "../Mutex.h"

#include <assert.h>
#include <stdio.h>

#include <functional>

using std::string;

class Stock : boost::noncopyable
{
public:
Stock(const string& name)
: name_(name)
{
printf(" Stock[%p] %s\n", this, name_.c_str());
}

~Stock()
{
printf("~Stock[%p] %s\n", this, name_.c_str());
}

const string& key() const { return name_; }

private:
string name_;
};

namespace version1
{

// questionable code
class StockFactory : boost::noncopyable
{
public:

std::shared_ptr<Stock> get(const string& key)
{
muduo::MutexLockGuard lock(mutex_);
std::shared_ptr<Stock>& pStock = stocks_[key];
if (!pStock)
{
pStock.reset(new Stock(key));
}
return pStock;
}


private:
mutable muduo::MutexLock mutex_;
std::map<string, std::shared_ptr<Stock> > stocks_;
};

}

namespace version2
{

class StockFactory : boost::noncopyable
{
public:
std::shared_ptr<Stock> get(const string& key)
{
std::shared_ptr<Stock> pStock;
muduo::MutexLockGuard lock(mutex_);
std::weak_ptr<Stock>& wkStock = stocks_[key];
pStock = wkStock.lock();
if (!pStock)
{
pStock.reset(new Stock(key));
wkStock = pStock;
}
return pStock;
}

private:
mutable muduo::MutexLock mutex_;
std::map<string, std::weak_ptr<Stock> > stocks_;
};

}

namespace version3
{

class StockFactory : boost::noncopyable
{
public:

std::shared_ptr<Stock> get(const string& key)
{
std::shared_ptr<Stock> pStock;
muduo::MutexLockGuard lock(mutex_);
std::weak_ptr<Stock>& wkStock = stocks_[key];
pStock = wkStock.lock();
if (!pStock)
{
pStock.reset(new Stock(key), std::bind_front(&StockFactory::deleteStock, this));
wkStock = pStock;
}
return pStock;
}

private:

void deleteStock(Stock* stock)
{
printf("deleteStock[%p]\n", stock);
if (stock)
{
muduo::MutexLockGuard lock(mutex_);
stocks_.erase(stock->key()); // This is wrong, see removeStock below for correct implementation.
}
delete stock; // sorry, I lied
}
mutable muduo::MutexLock mutex_;
std::map<string, std::weak_ptr<Stock> > stocks_;
};

}

namespace version4
{

class StockFactory : public std::enable_shared_from_this<StockFactory>,
boost::noncopyable
{
public:

std::shared_ptr<Stock> get(const string& key)
{
std::shared_ptr<Stock> pStock;
muduo::MutexLockGuard lock(mutex_);
std::weak_ptr<Stock>& wkStock = stocks_[key];
pStock = wkStock.lock();
if (!pStock)
{
pStock.reset(new Stock(key),
std::bind_front(&StockFactory::deleteStock, shared_from_this()));
wkStock = pStock;
}
return pStock;
}

private:

void deleteStock(Stock* stock)
{
printf("deleteStock[%p]\n", stock);
if (stock)
{
muduo::MutexLockGuard lock(mutex_);
stocks_.erase(stock->key()); // This is wrong, see removeStock below for correct implementation.
}
delete stock; // sorry, I lied
}
mutable muduo::MutexLock mutex_;
std::map<string, std::weak_ptr<Stock> > stocks_;
};

}

class StockFactory : public std::enable_shared_from_this<StockFactory>,
boost::noncopyable
{
public:
std::shared_ptr<Stock> get(const string& key)
{
std::shared_ptr<Stock> pStock;
muduo::MutexLockGuard lock(mutex_);
std::weak_ptr<Stock>& wkStock = stocks_[key];
pStock = wkStock.lock();
if (!pStock)
{
pStock.reset(new Stock(key),
std::bind_front(&StockFactory::weakDeleteCallback,
std::weak_ptr<StockFactory>(shared_from_this())));
wkStock = pStock;
}
return pStock;
}

private:
static void weakDeleteCallback(const std::weak_ptr<StockFactory>& wkFactory,
Stock* stock)
{
printf("weakDeleteStock[%p]\n", stock);
std::shared_ptr<StockFactory> factory(wkFactory.lock());
if (factory)
{
factory->removeStock(stock);
}
else
{
printf("factory died.\n");
}
delete stock; // sorry, I lied
}

void removeStock(Stock* stock)
{
if (stock)
{
muduo::MutexLockGuard lock(mutex_);
auto it = stocks_.find(stock->key());
if (it != stocks_.end() && it->second.expired())
{
stocks_.erase(stock->key());
}
}
}

private:
mutable muduo::MutexLock mutex_;
std::map<string, std::weak_ptr<Stock> > stocks_;
};

void testLongLifeFactory()
{
std::shared_ptr<StockFactory> factory(new StockFactory);
{
std::shared_ptr<Stock> stock = factory->get("NYSE:IBM");
std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");
assert(stock == stock2);
// stock destructs here
}
// factory destructs here
}

void testShortLifeFactory()
{
std::shared_ptr<Stock> stock;
{
std::shared_ptr<StockFactory> factory(new StockFactory);
stock = factory->get("NYSE:IBM");
std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");
assert(stock == stock2);
// factory destructs here
}
// stock destructs here
}

int main()
{
version1::StockFactory sf1;
version2::StockFactory sf2;
version3::StockFactory sf3;
std::shared_ptr<version3::StockFactory> sf4(new version3::StockFactory);
std::shared_ptr<StockFactory> sf5(new StockFactory);

{
std::shared_ptr<Stock> s1 = sf1.get("stock1");
}

{
std::shared_ptr<Stock> s2 = sf2.get("stock2");
}

{
std::shared_ptr<Stock> s3 = sf3.get("stock3");
}

{
std::shared_ptr<Stock> s4 = sf4->get("stock4");
}

{
std::shared_ptr<Stock> s5 = sf5->get("stock5");
}

testLongLifeFactory();
testShortLifeFactory();
}
Loading