先贴出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要用到的内存的起始指针)