本文主要是介绍php中ZTS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.ZTS zend thread safety,php线程安全,适用于Apache2+worker MPM
2.ts_allocate_id:allocates a new thread-safe-resource id;函数 TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);rsrc_id是指针类型,会在ts_allocate_id函数内部给出值;ctor/dtor资源初始化和销毁的函数指针
tsrm_tls_entry:每个线程拥有一个tsrm_tls_entry结构,当前线程的所有资源保存在storage数组中,storage中的下标就是各资源的id,由ts_allocate_id分配;
struct _tsrm_tls_entry {void **storage;int count;THREAD_T thread_id;tsrm_tls_entry *next;
};
tsrm_tls_table:所有线程的tsrm_tls_entry结构通过一个数组保存:tsrm_tls_table,这是个全局变量,每个线程的tsrm_tls_entry结构在这个数组中的位置是根据线程id与预设置的线程数(tsrm_tls_table_size)取模得到的,也就是说有可能多个线程保存在tsrm_tls_table同一位置,所以tsrm_tls_entry是个链表,查找资源时首先根据:线程id % tsrm_tls_table_size得到一个tsrm_tls_entry,然后开始遍历链表比较thread_id确定是否是当前线程的。
tsrm_tls_table结构如图:
3.ts_allocate_id源码赏析
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{/*{{{*/int i;TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));tsrm_mutex_lock(tsmm_mutex);//锁/* obtain a resource id */*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);//分配资源idTSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));/* store the new resource type in the resource sizes table */if (resource_types_table_size < id_count) {//线程中的所有不共享的全局资源表tsrm_resource_type *_tmp;_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);if (!_tmp) {tsrm_mutex_unlock(tsmm_mutex);TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));*rsrc_id = 0;return 0;}resource_types_table = _tmp;resource_types_table_size = id_count;}/**为当前资源构建tsrm_resource_type结构**/resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;//构造函数resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;//析构函数resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;/* 遍历线程资源表tsrm_tls_table_size,为每一个线程的资源中添加新加入的这个资源,并初始化*/for (i=0; i<tsrm_tls_table_size; i++) {tsrm_tls_entry *p = tsrm_tls_table[i];//取出线程资源链表的表头,thread_id%thread_size == iwhile (p) {//对链表中的每一项做处理if (p->count < id_count) {int j;p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);for (j=p->count; j<id_count; j++) {p->storage[j] = (void *) malloc(resource_types_table[j].size);if (resource_types_table[j].ctor) {resource_types_table[j].ctor(p->storage[j]);}}p->count = id_count;}p = p->next;}}tsrm_mutex_unlock(tsmm_mutex);TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));return *rsrc_id;
}/*}}}*/
这篇关于php中ZTS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!