自己实现一个 线程池

我们先来看看一个网友写的  SafeObjectPool :

https://www.cnblogs.com/kellynic/p/9768452.html

 

从  SafeObjectPool , 我们大概可以自己实现一个 线程池, 比如

 

var pool = new SafeObjectPool.ObjectPool<Thread>();

 

Thread thread = pool.Get();

thread.唤醒();

 

唤醒后, thread 会进入 就绪队列, 很快就可以执行了 。

 

这样算可以实现一个 线程池 了吧 ?

 

 

以下 内容 补充于     2020 年 2 月 28 日  :

 

我发现 这篇 文章 的 阅读量 在 我的 博客 里 还算是 比较 高 的,  哈哈  。

之前 写过 这篇 文章 后,    我 自己 写了一下  线程池,   但是发现,   自己 实现 线程池 存在 一些问题,   这部分 好像 没有 记录 到 后来 的 博客 里,  所以 就 补充 在 这里  。

 

自己 实现 线程池,  需要 自己 管理 线程, 比如 用 C# 实现 线程池 的 话,  要 把  Thread  对象 放到 执行队列 和 空闲队列 里,   因为 线程池 对 线程 的 调度 本身 就是 一个 并发环境 下 的 操作,     所以,  对 队列 的 操作 需要 同步(Lock)  ,        然而,  如果用 C# 的 lock 关键字(Monitor.Enter() )  的 话,  这是 使用 操作系统 的 lock 原语,    性能不算太高   。  

当然,  可以 用  System.Collections.Concurrent    里 的   ConcurrentQueue<T>  ,    System.Collections.Concurrent   里 的 集合 的 并发同步 可能是 用 CAS 指令 实现 的 Lock ,     如果 是 这样 ,   性能 就 很高,   性能 应该 是  是  C# lock 关键字  的  10 倍   。

但 即使 这样,   操作系统 内核 自身 对 线程 的 调度 的 效率 应该 更高   。

 

另外一个 问题 是,     在 C# 里,  可以调用 Thread  的  Suspend() 、 Resume()  等 方法  把 Thread  挂起 和 恢复  等,    但,  这些 方法,  最终 是要 通知  操作系统 ,  由  操作系统 完成  线程状态 的 切换,     所以,  当 调用了  Suspend()   方法 完成时,   在 操作系统 层面,  该 线程  已经 进入 了 挂起 状态 ?  或者 是,  调用了  Suspend()   方法 , 仅仅是  发了一个 请求 告诉 操作系统 要 把 这个 线程 挂起,  这个  请求 在 操作系统 里 排队 执行,  所以,  调用了  Suspend()   方法 完成时 ,  并 不能 确定 在  操作系统 层面 ,  该 线程 是否 已经 挂起  ?    又或者 是 其它 的 情况   ?      

 

不知道  。

 

所以,  在 C# 层面,  调用了  Suspend()   方法,   如果 在 操作系统 层面  该 线程 还没有 进入 挂起 状态,  而 因为 有 新的 任务 添加到 线程池,   C# 又 接着 调用了  Resume()  方法,   此时 会 如何 , 会否 报错 , 或者 发生 其它 意想不到 的 事  ?

 

所以,    在 C# 层面 对 线程 进行 管理 ,   又 涉及 到 并发(多个 线程 向 线程池 并发 的 添加 任务),    这个 管理 是否 安全 可靠 ?  不知道  。

 

所以,  看起来,  还是 操作系统 自身 提供 线程池,  才是 高效 、安全 的 方式   。

 

调度线程 是 操作系统 内核 的 核心工作,   操作系统 本身 就会 维护  就绪队列 和 挂起队列,    所以,  在 操作系统 之外,    由 语言(应用程序) 自己 再来 维护 一个    执行队列  和  空闲队列    是否 是 重复 的 或者 多此一举  ?

 

我在 QQ 群 里 听  网友 说,   C# 团队 本来 也想 自己 实现一个 线程池,   但是 因为 效率 不高,  所以 放弃了,   还是使用 Windows 线程池  。

 

在  线程池 之后,   我 研究 过 协程,  也就是   Goroutine ,    Coroutine   之类,      我当时想 要 实现 协程 需要  语言 自己 实现一个   线程池,     但 上面 又说 线程池 不适合  语言 自己 实现,    这是怎么回事 ?                需要 把 之前 的 想法 整理一下   。

2021-08-27  补充 :

前不久, 5 月份吧,    我写了一个  线程池 :        https://github.com/kelin-xycs/EasyThreadPool     。

 

原文地址:https://www.cnblogs.com/KSongKing/p/9803935.html