swoole源码分析

本文主要探讨了swoole_server的源码分析,从PHP层面出发,重点研究了`__construct`方法,涉及swServer对象的创建与初始化,以及SwooleG和SwooleWG对象的初始化过程。文中提到了sw_shm_malloc的机制,它是如何为内存分配并插入swShareMemory对象的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先贴出php的代码 php 内核方面关于 zend api 以后有时间会再做 学习的

$server = new Server("0.0.0.0", 9501);
$server->set(array(
    'worker_num' => 1,
    'daemonize' => true,
//    'max_request' => 50000,
//    'dispatch_mode' => 2,
//    'package_max_length' => 4096,
    'open_length_check' => true,
    'package_length_offset' => 0,
    'package_body_offset' => 0,
    'package_length_type' => "N",//0 后 N(4位)是长度
    'open_cpu_affinity' => true,
    'log_file' => dirname(__FILE__) . '/log/socket.log'
));
$server->on('connect', function ($server, $fd){
    echo "Client{$fd}:Connect.\n";
});
$server->on('Start', function () {
    swoole_set_process_name("sw_t_master_main_soft");
});
$server->on('ManagerStart', function () {
    swoole_set_process_name("sw_t_manager_main_soft");
});
$server->on('WorkerStart', function ($server, $worker_id) use($ip) {
    swoole_set_process_name("sw_t_worker_main_soft");
    /**
     * 初始化程序
     */
});
$server->on('receive', function (Server $server, $fd, $from_id, $data) {
    try{
         /**
          * 业务处理
          */
        }
    }catch (ErrorException $e){
        printLn($e->getMessage());
    }catch (Exception $e){
        printLn($e->getMessage());
        $server->close($fd);
    }
});
$server->on('close', function (Server $server, $fd) use($ip) {
    echo "Client{$fd}: Close.\n";
});

找到 源码中的swoole_server.c 中的代码
定位到 PHP_METHOD(swoole_server, __construct){…}这里 也就是 server的构造方法.

function __construct($host, $port, $mode = SWOOLE_PROCESS, $sock_type = SWOOLE_SOCK_TCP)
/**
 * new swoole_server 构造函数参数
 */
define('SWOOLE_PROCESS', 3); //使用进程模式,业务代码在Worker进程中执行
define('SWOOLE_SOCK_TCP', 1); //创建tcp socket

创建 swServer 对象 并初始化
创建 SwooleG 对象 并初始化 //Local Global Variable
swooleG中系统的一些参数,和 memory_pool
创建 SwooleWG 对象 并初始化 //Worker Global Variable

    swServer *serv = sw_malloc(sizeof (swServer));
    bzero(&SwooleG, sizeof(SwooleG));
    bzero(&SwooleWG, sizeof(SwooleWG));
    SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1);
    //init global lock
    swMutex_create(&SwooleGS->lock, 1);
    swMutex_create(&SwooleGS->lock_2, 1);
    swMutex_create(&SwooleG.lock, 0);

分析

swMemoryPool* swMemoryGlobal_new(int pagesize, char shared)
{
    swMemoryGlobal gm, *gm_ptr;
    assert(pagesize >= SW_PAGE_SIZE);
    bzero(&gm, sizeof(swMemoryGlobal));
    gm.shared = shared;
    gm.pagesize = pagesize;
    void *first_page = swMemoryGlobal_new_page(&gm); //第一页的指针
    if (first_page == NULL)
    {
        return NULL;
    }
    //分配内存需要加锁 创建 互斥锁
    if (swMutex_create(&gm.lock, 1) < 0)
    {
        return NULL;
    }
    //root
    gm.root_page = first_page;
    gm.cur_page = first_page;

    gm_ptr = (swMemoryGlobal *) gm.mem;
    gm.offset += sizeof(swMemoryGlobal);

    swMemoryPool *allocator = (swMemoryPool *) (gm.mem + gm.offset);
    gm.offset += sizeof(swMemoryPool);

    allocator->object = gm_ptr;
    allocator->alloc = swMemoryGlobal_alloc;
    allocator->destroy = swMemoryGlobal_destroy;
    allocator->free = swMemoryGlobal_free;

    memcpy(gm_ptr, &gm, sizeof(gm));
    return allocator;
}
void* sw_shm_malloc(size_t size)
{
    swShareMemory object;
    void *mem;
    //object对象需要保存在头部
    size += sizeof(swShareMemory);
    mem = swShareMemory_mmap_create(&object, size, NULL);//所有mem的 开始地址
    if (mem == NULL)
    {
        return NULL;
    }
    else
    {
        memcpy(mem, &object, sizeof(swShareMemory));
        return mem + sizeof(swShareMemory);//真实的mem地址
    }
}

sw_shm_malloc个人的理解是 得到一片size+sizeof(swShareMemory)大小的内存块
把 swShareMemory对象插入 内存的起始位置 并返回 之后的指针(size要用到的内存的起始指针)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值