Build Your Own Threadpool With C++

Why Threadpool Matters

Why on the earth do we need thread-pool? The answer is obvious: for doing jobs behind the scenes.

That is, saying, you have a constant stream of incoming tasks to complete, and most of which either incur heavy computation or invovle device I/O, you definitely don’t want to execute them on your main thread, because it will block your main thread until the job is done, making your application less responsive.

However, with thread-pool, you can simply submit a task to the pool, then continue what was doing; the task will eventually be completed on a thread of the thread-pool.

If your processor has multiple cores, the task is possibly performed concurrently with your jobs on the main thread.

What Should a Threadpool Provide

Before we switch our focus to editor, we are better to think twice about what we can do with the thread-pool we will build.

Read More

浅析 RefCounted 和 WeakPtr:Chromium Base 篇

序言请移步此处

MSVC STL 的分析版本请移步此处

Libstdc++ 的分析版本请移步此处

Boost 的分析版本请移步此处

注 1:因为这不是第一篇分析,所以会直入主题,跳过文学写作常用的累赘的过渡。

注 2:这是系列最后一篇。

目标版本选择

Chromium tag 68.0.3421.1

代码位置:base/memory/ref_counted.{h, cc}

RefCountedBase 和 RefCounted

两个类实现了非线程安全的引用计数,即:内部计数使用的是 built-in integer

先看看 RefCountedBase 的大致结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class RefCountedBase {
protected:
explicit RefCountedBase(StartRefCountFromZeroTag);

explicit RefCountedBase(StartRefCountFromOneTag);

~RefCountedBase();

void AddRef() const;

bool Release() const;

private:
mutable uint32_t ref_count_ = 0;

#if DCHECK_IS_ON()
mutable bool needs_adopt_ref_ = false;
mutable bool in_dtor_ = false;
mutable SequenceChecker sequence_checker_;
#endif

DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
};

可以看出核心 ref_count_ 类型是 uint32_t

ctor 和 dtor 都被定义为 protected,说明这类使用做基类;同时提供了 AddRef()Release(),进行内部的计数增减。

Read More

浅析 shared_ptr:Boost 篇

序言请移步此处

MSVC STL 的分析版本请移步此处

Libstdc++ 的分析版本请移步此处

注:因为这不是第一篇分析,所以会直入主题,跳过文学写作常用的累赘的过渡。

目标版本选择

选用最新的 Boost 1.67 作为研究目标

在开始正题前,先简单看一下 shared_ptr 的类成员,方便后续分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace detail {

template< class T > struct sp_element
{
typedef T type;
};

}

template<class T>
class shared_ptr {
public:
typedef typename boost::detail::sp_element< T >::type element_type;

// omitted other

private:
element_type * px; // contained pointer
boost::detail::shared_count pn; // reference counter
};

Read More

Monthly Read Post in Apr 2018

What is Load Balancing?

Digital Ocean 出品的良心文章,覆盖了:

    Read More

    std::function Must be Copyable

    前几天在写一个 ThreadPool 的轮子的时候,碰到一个问题:无论我用什么办法,都不能将 std::packaged_task 传递到 std::function 中,编译器始终提示访问了 std::packaged_task 被删除的拷贝构造函数。

    Read More

    Use Lambda With PostTask

    曾经为了能在 PostTask() 里使用 lambda,实现了一个自动将 non-capturing lambda decay 到对应函数指针,在利用 base::Bind() 的方案[1]

    Read More

    利用 vcpkg 编译带汇编优化的 libx264

    使用 vcpkg 编译 libx264 有一个很重要的原因:可以获得 PDB,而且构建流程被大大精简了。

    但是这里有一个坑:vcpkg 上的 libx264 模块编译默认是开启了 --disable-asm,意味着构建之后的二进制不会使用 SIMD 指令集,所以性能上会有很大的问题。

    Read More