资讯专栏INFORMATION COLUMN

协程 C/C++ 扩展开发指南(1):内存安全

KavenFan / 2292人阅读

摘要:有很多的扩展在开发时未能考虑到并发性可重入问题,导致无法在协程中使用。本文会详细讲解如何编写协程并发安全的代码。协程将自身栈内存的指针发送给另外一个协程,协程退出时会释放协程栈内存。协程的生命周期长于,继续读写此内存,就会导致。

Swoole4 协程的出现使得 PHP 底层上从原来串行模式变成了并发模式。有很多 PHP 的C/C++扩展在开发时未能考虑到并发性、可重入问题,导致无法在Swoole协程中使用。本文会详细讲解如何编写协程并发安全的C/C++代码。

可重入性

示例代码:

int t;

void test1(int *x, int *y) {
    t = *x;
    *x = *y;
    //fun1 函数中可能会存在协程切换
    fun1();
    //错误代码
    *y = t;
}

t是一个全局变量或者static静态变量

在协程A中调用了test1函数,使用了全局变量t

当函数内调用了fun1(),这个函数中如果发生了协程切换,这时假如另外一个协程B也执行了test1函数,那么t的值可能会被修改

协程B挂起时,重新回到协程A,这时*y = t,会得到一个错误的值

引用栈内存

这也是一个严重的风险点。协程1将自身栈内存的指针发送给另外一个协程2,协程1退出时会释放协程栈内存。协程2的生命周期长于1,继续读写此内存,就会导致segment fault

示例:

void co1() {
    char buf[2048];
    //这里启动一个新的协程,buf 是协程1栈上内存
    co2(buf);
    //协程1 退出时会释放栈内存
}

void co2(char *buf) {
    for(int i=0; i<2048; i++) {
        Coroutine::sleep(1);
        //这里 buf 内存可能已经释放了
        buf[i] = 1;
    }
}
协程安全代码

为了保证安全性,在Swoole4协程编程中:

不要使用static变量和全局变量,坚持只用局部变量

若必须访问全局变量,必须保证只用于计算逻辑,不得存在任何IOSleep等引起协程切换的操作

不调用其它任何不可重入的函数

不要引用栈上内存

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31013.html

相关文章

  • PHP并发IO编程之路

    摘要:下文如无特殊声明将使用进程同时表示进程线程。收到数据后服务器程序进行处理然后使用向客户端发送响应。现在各种高并发异步的服务器程序都是基于实现的,比如。 并发 IO 问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接 Fork 进程,到 Worker 进程池/线程池,到现在的异步IO、协程。PHP 程序员因为有强大的 LAMP 框架,对这类底层方面的知识知之甚少,本文目的就是详细介...

    Riddler 评论0 收藏0
  • PHP程序员学习路线

    摘要:第一阶段基础阶段基础程序员重点把搞熟练核心是安装配置基本操作目标能够完成基本的系统安装,简单配置维护能够做基本的简单系统的开发能够在中型系统中支持某个功能模块的开发。本项不做重点学习,除非对前端有兴趣。 第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护;能够做基本的简单系统的PHP开发;能够在P...

    genedna 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<