《PHP扩展开发》-协程-协程getCid.md 3.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
# 协程getCid

在上篇文章中,我们写了如下测试脚本:

```php
<?php

function task($n, $arg)
{
	echo "coroutine [$n] create" . PHP_EOL;
	Study\Coroutine::yield();
	echo "coroutine [$n] be resumed" . PHP_EOL;
}

echo "main coroutine" . PHP_EOL;
Study\Coroutine::create('task', 1, 'a');
echo "main coroutine" . PHP_EOL;
Study\Coroutine::create('task', 2, 'b');
echo "main coroutine" . PHP_EOL;

Study\Coroutine::resume(1);
echo "main coroutine" . PHP_EOL;
Study\Coroutine::resume(2);
echo "main coroutine" . PHP_EOL;
```

我们的协程任务函数`task`有一个参数`$n`,它是用来接收协程id的。很显然,这是不友好的。我们在开发的时候肯定不可能这样做对吧。所以我们需要提供一个接口来获取当前协程的id。

我们在`study_coroutine_util.cc`中进行实现:

```cpp
PHP_METHOD(study_coroutine_util, getCid)
{
    Coroutine* co = Coroutine::get_current();
    RETURN_LONG(co->get_cid());
}
```

然后注册这个函数:

```cpp
PHP_ME(study_coroutine_util, getCid, arginfo_study_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
```

然后编译、安装:

```shell
make clean && make && make install
```

编写如下脚本进行测试:

```php
<?php

function task($arg)
{
	$cid = Study\Coroutine::getCid();
	echo "coroutine [{$cid}] create" . PHP_EOL;
	Study\Coroutine::yield();
	echo "coroutine [{$cid}] create" . PHP_EOL;
}

echo "main coroutine" . PHP_EOL;
Study\Coroutine::create('task', 'a');
echo "main coroutine" . PHP_EOL;
Study\Coroutine::create('task', 'b');
echo "main coroutine" . PHP_EOL;

Study\Coroutine::resume(1);
echo "main coroutine" . PHP_EOL;
Study\Coroutine::resume(2);
echo "main coroutine" . PHP_EOL;
```

执行脚本:

```shell
~/codeDir/cppCode/study # php test.php 
main coroutine
coroutine [1] create
main coroutine
coroutine [2] create
main coroutine
coroutine [1] create
main coroutine
coroutine [2] create
main coroutine
~/codeDir/cppCode/study # 
```

OK,符合预期。

我们发现,我们的`resume`也是传递一个字面值,很明显,这个协程id应该是从`Study\Coroutine::create`返回的才对。所以我们改进`Study\Coroutine::create`这个接口:

```cpp
PHP_METHOD(study_coroutine_util, create)
{
    // 前面的代码没有改变

    long cid = PHPCoroutine::create(&fcc, fci.param_count, fci.params);
    RETURN_LONG(cid);
}
```

我们返回了协程的id。

OK,我们重新编译、安装:

```shell
make clean && make && make install
```

然后我们修改脚本:

```php
<?php

function task($arg)
{
	$cid = Study\Coroutine::getCid();
	echo "coroutine [{$cid}] create" . PHP_EOL;
	Study\Coroutine::yield();
	echo "coroutine [{$cid}] create" . PHP_EOL;
}

echo "main coroutine" . PHP_EOL;
$cid1 = Study\Coroutine::create('task', 'a');
echo "main coroutine" . PHP_EOL;
$cid2 = Study\Coroutine::create('task', 'b');
echo "main coroutine" . PHP_EOL;

Study\Coroutine::resume($cid1);
echo "main coroutine" . PHP_EOL;
Study\Coroutine::resume($cid2);
echo "main coroutine" . PHP_EOL;
```

然后执行:

```shell
~/codeDir/cppCode/study # php test.php 
main coroutine
coroutine [1] create
main coroutine
coroutine [2] create
main coroutine
coroutine [1] create
main coroutine
coroutine [2] create
main coroutine
~/codeDir/cppCode/study # 
```

符合预期。

157 158
[下一篇:修复一些bug(一)](./《PHP扩展开发》-协程-修复一些bug(一).md)

159 160 161 162 163 164 165 166