之前使用golang40行代码实现了通用协程池。今天看了swoole的相关文档,用PHP实现了一个。由于swoole没有golangselect,实现起来有点简单,但是实用性还可以,通用性是通过工厂函数来实现的。Swoole官方的协程池只能在Redis中使用。因为协程池代码层耦合了Redis的实例化逻辑。classRedisPool{/***@var\Swoole\Coroutine\Channel*/protected$pool;/***RedisPool构造函数。*@paramint$size连接池的尺寸*/function__construct($size=100){$this->pool=newSwoole\Coroutine\Channel($size);for($i=0;$i<$size;$i++){$redis=newSwoole\Coroutine\Redis();$res=$redis->connect('127.0.0.1',6379);if($res==false){thrownewRuntimeException("无法连接Redis服务器。");}else{$this->put($redis);}}}函数put($redis){$this->pool->push($redis);}functionget(){return$this->pool->pop();}}利用工厂方法的修改如下:size=$size;$this->factory=$factory;$this->初始化();}/***检查池配置*@throwsInvalidParamException*/privatefunctioninit(){if($this->size<=0){thrownewInvalidParamException('“大小”属性必须大于零。');}if(empty($this->factory)){thrownewInvalidParamException('必须设置“工厂”属性。');}如果是_callable($this->factory)){thrownewInvalidParamException('“工厂”属性必须是可调用的。');}$this->bootstrap();}/***引导池*/privatefunctionbootstrap(){$this->channel=newChannel($this->size);对于($i=0;$i<$this->size;$i++){$this->channel->push(call_user_func($this->factory));}}/***获取连接*@paramint$timeout*@returnmixed*/publicfunctionacquire($timeout=0){return$this->channel->pop($timeout);}/***释放资源*@parammixed$resource*/publicfunctionrelease($resource){$this->channel->push($resource);}}我们代码中不关心创建连接的具体逻辑,只要调用工厂方法即可,项目地址项目已经开源到githubhttps://github.com/swoole-foundation/swoole-水池
