swoole mysql 协程_Swoole之协程篇

2ff34e647e2e3cdfd8dca593e17d9b0a.png

CPU一次只能对一个进程做处理。

进程有自己独立的地址空间,是资源分配和拥有的单位。进程之间数据不共享,进程内至少有一个线程。

线程是处理器调度的最小单位,是进程内的一个执行单元,同一个进程内的线程共享进程的地址空间和资源。

协程的本质是将线程的调度权还给了程序本身,而不是CPU。所以协程也称用户态的轻量型线程。

以官方文档为主,地址点我

创建一个新的协程,并立即执行。1

2function SwooleCoroutine::create(callable $function, ...$args) : int|false;

function go(callable $function, ...$args) : int|false; // 短名API

$function 协程执行的代码,必须为callable,系统能创建的协程总数量受限于server->max_coroutine设置。创建失败返回false,创建成功返回协程的ID。

CoroutineSystem::sleep

进入等待状态。相当于PHP的sleep函数,不同的是Coroutine::sleep是协程调度器实现的,底层会yield当前协程,让出时间片,并添加一个异步定时器,当超时时间到达时重新resume当前协程,恢复运行。使用sleep接口可以方便地实现超时等待功能。使用sleep模拟IO阻塞,会引起协程的切换(进入调度队列)1function CoroutineSystem::sleep(float $seconds);

$seconds为睡眠的时间,单位为秒,支持浮点型,最小精度为毫秒(0.001秒)。必须大于0,最大不得超过一天时间(86400秒)

CoroutineChannel

通道,类似于go语言的chan,支持多生产者协程和多消费者协程。底层自动实现了协程的切换和调度。

Channel->push 当队列中有其他协程正在等待pop数据时,自动按顺序唤醒一个消费者协程。当队列已满时自动yield让出控制器,等待其他协程消费数据

Channel->pop 当队列为空时自动yield,等待其他协程生产数据。消费数据后,队列可写入新的数据,自动按顺序唤醒一个生产者协程。

简单代码示例如下1

2

3

4

5

6

7

8

9

10

11

12

13use SwooleCoroutine as co;

$chan=new coChannel(1); // 容量为1 最小为1

go(function() use($chan){ //只负责 计算 cpu

$count=0;

for($i=1;$i<=3;$i++){

$count=$count+$i;

co::sleep(1);

}

$chan->push($count);

});

go(function() use($chan){ //只负责输出 IO

echo $chan->pop().PHP_EOL;

});

Coroutine::yield

让出当前协程的执行权。 此方法拥有另外一个别名:Coroutine::suspend()1function Coroutine::yield();

必须与Coroutine::resume()方法成对使用。该协程yield以后,必须由其他外部协程resume,否则将会造成协程泄漏,被挂起的协程永远不会执行。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17use SwooleCoroutine as co;

$cid = go(function(){

for($i=1;$i<=10;$i++){

if($i==6){

co::yield();

}

echo $i.PHP_EOL;

// co::sleep(0.2); // 当IO存在堵塞时发生协程切换 进入调度队列 没有堵塞的话看起来是顺序执行

}

});

go(function() use ($cid){

for($i=1;$i<=10;$i++){

echo 'a'.$i.PHP_EOL;

}

co::resume($cid);

});

CoroutineHttpClient

协程版Http客户端基于原生的异步Http客户端,基本的设置和使用方法和异步Http客户端一致,不在需要注册回调函数,只需要同步写法即可1

2

3

4

5

6

7

8

9

10

11

12go(function(){

$cli = new SwooleCoroutineHttpClient('192.168.2.156', 8082);

$cli->get('/index.php?t=123123');

echo $cli->body;

$cli->close();

});

go(function(){

$cli = new SwooleCoroutineHttpClient('192.168.2.156', 8082);

$cli->get('/index.php');

echo $cli->body;

$cli->close();

});

如果未设置timeout,则将底层connect和request超时设置为默认的500ms

Runtime

在4.1.0版本中,底层增加一个新的特性,可以在运行时动态将基于php_stream实现的扩展、PHP网络客户端代码一键协程化。1

2function Runtime::enableCoroutine(bool $enable = true, int $flags = SWOOLE_HOOK_ALL);

function Runtime::enableCoroutine(int $flags = SWOOLE_HOOK_ALL);

$enable:打开或关闭协程 $flags:选择要Hook的类型,可以多选,默认为全选。仅在$enable = true时有效

需要留意官方文档中的可用列表和不可用列表1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23SwooleRuntime::enableCoroutine();

function getHtml2($t=false){

$fp=stream_socket_client("tcp://192.168.2.156:8082");

$path="/index.php";

if($t) $path.="?".$t;

fwrite($fp, "GET $path HTTP/1.0rnAccept: */*rnrn");

$ret="";

while (!feof($fp)) {

$ret.=fgets($fp, 1024);

}

fclose($fp);

return $ret;

}

go(function(){

echo getHtml2("t=123");

});

go(function(){

echo getHtml2();

});

// 其他代码段不贴了,当传参t时,sleep一秒后执行

// 目前Runtime函数支持stream_socket_client协程化,所以运行结果 输出先 getHtml2()的内容,后getHtml2("t=123")

// 当然Swoole存在内置函数,可以直接实现协程化,见CoroutineHttpClient

CoroutineMySQL

请勿同时使用异步回调和协程MySQL

使用MySQL协程客户端是否要关闭?1

2

3

4

5

6

7

8

9$swoole_mysql = new SwooleCoroutineMySQL();

$swoole_mysql->connect([

'host' => '127.0.0.1',

'port' => 3306,

'user' => 'user',

'password' => 'pass',

'database' => 'test',

]);

$res = $swoole_mysql->query('select sleep(1)');

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值