以前一直不明白不同语言之间相互调用的原理。直到后来看HotSpot的时候,看到了Java虚拟机调用C语言函数的方式,才明白一个道理,函数调用最基本的问题就是参数传递和值返回。参数传递和值返回的细节,其实已经是汇编层面的问题了。简单来说,就是把参数压入堆栈,然后把返回值(可能是指针)存放到约定的寄存器。不过实际上并不一定需要汇编层面的东西来支持。比如HotSpot主要是用C/C++写的,PHP是用C写的。所以调用JAVA和PHP调用C函数其实就比较简单了,毕竟执行引擎和虚拟机都是C或兼容C的。
PHPredis其实就是一个PHP扩展。我对PHP扩展的理解也不够深刻,半个月前都还不知道这东西是什么呢!依据我粗浅的理解,PHP扩展的机制和Linux内核的模块机制是相似的。在一定的时候加载,模块中定义了初始化函数和卸载函数和其他的接口函数。通过加载注册的操作,接口函数被导入到一个符号表中。然后就可以在PHP语言层的代码中使用这些函数了。这就实现了PHP的扩展。
以PHPredis来说吧!PHP和redis之间是需要通信的,redis是一个单独运行的进程。这种通信就是进程间通信了,甚至是远程通信了。这些都是需要用到系统调用或者封装了系统调用的操作系统API。这时候,PHP就需要使用PHP扩展来实现和redis通信的功能了。在https://github.com/nicolasff/phpredis可以看到PHPredis的工程。因为只是一个扩展,所以没有很多的代码,源文件也就几个。最长的redis.c也只有7000多行。通读一下的难度其实并不大,不过前提是要对redis比较了解。PHPredis本质上就是一个redis客户端。到目前为止对我redis还是不了解,感觉要慢慢去熟悉。值得注意的是PHPredis好像还实现了会话管理的功能。源码中明确定义了一句:
PHPredis其实就是一个PHP扩展。我对PHP扩展的理解也不够深刻,半个月前都还不知道这东西是什么呢!依据我粗浅的理解,PHP扩展的机制和Linux内核的模块机制是相似的。在一定的时候加载,模块中定义了初始化函数和卸载函数和其他的接口函数。通过加载注册的操作,接口函数被导入到一个符号表中。然后就可以在PHP语言层的代码中使用这些函数了。这就实现了PHP的扩展。
以PHPredis来说吧!PHP和redis之间是需要通信的,redis是一个单独运行的进程。这种通信就是进程间通信了,甚至是远程通信了。这些都是需要用到系统调用或者封装了系统调用的操作系统API。这时候,PHP就需要使用PHP扩展来实现和redis通信的功能了。在https://github.com/nicolasff/phpredis可以看到PHPredis的工程。因为只是一个扩展,所以没有很多的代码,源文件也就几个。最长的redis.c也只有7000多行。通读一下的难度其实并不大,不过前提是要对redis比较了解。PHPredis本质上就是一个redis客户端。到目前为止对我redis还是不了解,感觉要慢慢去熟悉。值得注意的是PHPredis好像还实现了会话管理的功能。源码中明确定义了一句:
#ifdef PHP_SESSION
extern ps_module ps_mod_redis;
#endif
在配置session的情况下支持session功能。在redis_session.c中定义了一个用链表实现的连接池,如代码所示:
typedef struct redis_pool_member_ {
RedisSock *redis_sock;
int weight;
int database;
char *prefix;
size_t prefix_len;
char *auth;
size_t auth_len;
struct redis_pool_member_ *next;
} redis_pool_member;
连接池链表可以避免套接字资源反复申请对cpu时间的浪费。显而易见的可以想到,在服务器端,PHP对如redis的访问是很密集的,而且访问目标也基本不会有很大的变动,所以连接池应该是非常有效的。