您的位置:首页 > 产品设计 > 产品经理

给产品经理讲技术 | 复用的艺术:线程池

2016-03-29 00:00 639 查看

  学习编程必然绕不开多线程。实现一个功能,你既可以选择串行的方式,一条路走到天黑,也可以选择多线程,多条腿一起走。现在的CPU动辄四核八核的,如果自始至终只让一个核干活,那跟薅羊毛只薅一只羊有什么区别?

但是很快你就会了解到,线程这东西,也不是你想用、想用就能随便用的。

前几天的文章《你有空吗?跟我一起搭个服务器好不好?》和大家一起动手搭了一个服务器(其实就是装了一个叫Nginx的软件)。虽然简单,但是不影响我们学习服务器的原理:服务器就是用来接收并响应客户端的网络请求的。最简单的工作流程是,每次收到一个请求,就开一个线程去处理,这样可以最大化的利用CPU的并行处理能力。

但是,假如你同时接收10w个请求,也要开10w个线程吗?肯定是不可以的,原因有三:

操作系统都有线程分配的最大值,比如linux系统一般只允许分配1024个。第一关你首先过不了。

操作系统创建线程的时候需要同时分配一些内存,虽然服务器的内存都很大,但也不是用不完的,地主家也没有余粮,不是吗?

CPU创建一个线程和销毁一个线程是要花时间的,甭管多快,肯定比直接拿来用要慢吧。

如果不好理解,可以举个例子。

有一天你招了一帮码农帮你做需求。平时有需求的时候,大家很开心,一人分配一个,多线程并行工作,很快就交付了。没需求的时候呢,你嫌他们白拿工资,就全都fire掉了。这其实是不明智的。先不说你随便fire别人要付N+1,依现在的行情,招一个靠谱点儿的码农想必也是一个「众里寻他千百度」的事情吧。权衡一二,我还是建议你搞一个池子,把他们圈养起来,下次有需求了直接取,用完扔回池子里,只需要咬咬牙给他们发工资就行了。

线程池也是一样的道理。既然服务器不可能无上限的分配线程,那就弄个盛放线程的池子,先分配几个在里面放着,用到的时候直接取,用完再扔回去,循环往复,子子孙孙无穷尽也,岂不快哉?

原理就是这样的,那用什么来实现呢?

给你5秒钟想一下,想不出来的自觉打赏哈。

我们把问题抽象一下,现在有很多「请求」不断的涌入到你的服务器,同时你的服务器创建了一个线程池,里面有一堆可以「处理」请求的线程。这是什么?这是「生产者消费者模型」啊,想起来了没,讲过的哦。

在这个模型里,「生产者」就是一个个客户端,生产的是「网络请求」,「消费者」就是线程池里的线程,消费的也是「网络请求」,消费的过程就是响应网络请求的过程。当然,有时候网络请求太多,线程池里没有足够空闲的线程的时候,就会把请求放到一个队列里去排队。

所以你们双11的时候抢不到促销商品,可以理解为淘宝的服务器线程池里的线程用完了,你的请求被放到队列里去,等别人买完了让出线程才能轮到你。

这就是线程池的缺点,它可能会导致请求得不到及时的处理。但是这总比你一下在分配太多的线程直接把服务器搞挂掉要强吧?

程序员的世界里,像线程池这样的还有很多,比如对象池、连接池、指令池、炮友池等等。把一个东西「池化」是一种很典型的复用思想,它的核心就是,这些东西如果可以重复使用的话,就尽量不要销毁它。

线程池先讲到这里。然后是我叨逼叨的时间。有朋友说,你讲线程啊、面向对象啊、指针这些东西,作为产品经理平时压根就用不到嘛。仔细想想,好像确实是这么回事儿。但是我觉得人不能光盯着眼前能看到的这点儿地方,否则容易形成思维定式打不开局面。换言之,我希望你订阅这个公众号的目的,是渴望理解程序员的思维方式,避免被他们忽悠,或者仅仅是想做一个什么都懂的人,而不是像看《程序员面试宝典》或者《21天学会C++》那样,有非常明确的目的性、功利心。大概就是这么个意思,不知道我说明白了没有。

欢迎添加微信公众号:给产品经理讲技术

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  服务器 线程 请求