《PHP扩展开发》-协程-协程创建(六).md 3.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 协程创建(六)

这篇文章,我们开始实现`php_coro_task* PHPCoroutine::get_task()`

首先,我们认为有一个主协程,这是其他所有协程的开始。所以,我们在`Study::PHPCoroutine`中定义一个成员变量`main_task`,我希望它是`protected`的。在文件`study_coroutine.h`中定义:

```cpp
protected:
    static php_coro_task main_task;
```

然后,我们本来是可以这么实现`get_task()`的:

```cpp
C
codinghuang 已提交
15 16
php_coro_task PHPCoroutine::main_task = {0};

17 18 19 20 21 22 23 24 25 26 27 28
php_coro_task* PHPCoroutine::get_task()
{
    php_coro_task *task = PHPCoroutine::get_current_task();
    return task ? task : &main_task;
}
```

但是,我们希望这套协程库不仅仅适用于`PHP`,我们还希望以后可以适用于其他地方。所以我们获取当前协程的功能放在更加低层次的`Study::Coroutine`里面来实现它。

所以,我们应该这么实现`php_coro_task* PHPCoroutine::get_task()`

```cpp
C
codinghuang 已提交
29 30
php_coro_task PHPCoroutine::main_task = {0};

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
php_coro_task* PHPCoroutine::get_task()
{
    php_coro_task *task = (php_coro_task *) Coroutine::get_current_task();
    return task ? task : &main_task;
}
```

我们让`Coroutine::get_current_task()`返回一个`void`类型的指针,然后,根据我们上层需要的协程结构进行转换即可,这样我们的协程库就可以在多个地方使用了。所以,我们需要去实现`Study::Coroutine::get_current_task`

很显然,这个方法应该是`public`的,因为我们需要在`PHPCoroutine`这个类里面去调用它,所以我们做如下的声明,在文件`include/coroutine.h``Study::Coroutine`里面:

```cpp
public:
    static void* get_current_task();
```

然后,我们再在`Study::Coroutine`类里面定义一个`Study::Coroutine`类型的指针:

```cpp
protected:
    static Coroutine* current;
```

然后,我们在`src/coroutine`目录下创建一个文件`coroutine.cc`,然后在这个文件里面来实现`void * Coroutine::get_current_task`这个方法:

```cpp
#include "coroutine.h"

using Study::Coroutine;

C
codinghuang 已提交
61 62
Coroutine* Coroutine::current = nullptr;

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
void* Coroutine::get_current_task()
{
    return Coroutine::current ? Coroutine::current->get_task() : nullptr;
}
```

因为我们新创建了一个文件`coroutine.cc`,所以我们需要修改我们的`config.m4`文件:

```shell
study_source_file="\
    study.cc \
    study_coroutine.cc \
    study_coroutine_util.cc \
    src/coroutine/coroutine.cc \
    ${STUDY_ASM_DIR}make_${STUDY_CONTEXT_ASM_FILE} \
    ${STUDY_ASM_DIR}jump_${STUDY_CONTEXT_ASM_FILE}
"
```

新增了`src/coroutine/coroutine.cc`

最后,我们只需要实现一下`Study::Coroutine::get_task`即可,我们在`include/coroutine.h``Study::Coroutine`中进行声明:

```cpp
public:
    void* get_task();
```

然后在`src/coroutine/coroutine.cc`中进行实现:

```cpp
void* Coroutine::get_task()
{
    return task;
}
```

我们需要在`include/coroutine.h``Study::Coroutine`类里面去定义一下这个`task`成员变量:

```cpp
protected:
    void *task = nullptr;
```

C
codinghuang 已提交
107 108 109 110
这样,我们就实现了保存`PHP`协程栈的功能。

[下一篇:协程创建(七)](./《PHP扩展开发》-协程-协程创建(七).md)