2KB项目,专业的源码交易网站 帮助 收藏 每日签到

解决php trie_filter扩展,cpu高负载问题

  • 时间:2019-11-04 00:20 编辑:Eoin Burke-Kennedy 来源:2KB项目 阅读:520
  • 扫一扫,手机访问
  • 分享
摘要:在使用php trie_filter跑脚本,循环匹配关键词,发现cpu利用率达到了99%通过strace命令跟踪,发现进程在反复的打开读取和关闭.tree文件,trie_filter_load这个方法被反复调用。正常的情况,这个文件应该会一次读到内存中,在内存中查询匹

在使用php trie_filter跑脚本,循环匹配关键词,发现cpu利用率达到了99%


通过strace命令跟踪,发现进程在反复的打开读取和关闭.tree文件,trie_filter_load这个方法被反复调用。


正常的情况,这个文件应该会一次读到内存中,在内存中查询匹配关键词。


追踪到扩展源码如下:

PHP_FUNCTION(trie_filter_load)
{
    Trie *trie;
    char *path;
    int path_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
                &path, &path_len) == FAILURE) {
        RETURN_NULL();
    }

    trie = trie_new_from_file(path);
    if (!trie) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                "Unable to load %s", path);
        RETURN_NULL();
    }

    ZEND_REGISTER_RESOURCE(return_value, trie, le_trie_filter);
}

 

trie变量保存的是一个Trie *结构体,还不能保证已读取到内存中,打开libdatrie源码,查找到.datrie/trie.c

Trie *
trie_new_from_file (const char *path)
{
    Trie       *trie;
    FILE       *trie_file;

    trie_file = fopen (path, "r");
    if (!trie_file)
        return NULL;

    trie = trie_fread (trie_file);
    fclose (trie_file);
    return trie;
}

trie 结构体读取并保存了文件内容,再定位trie_fread

Trie *
trie_fread (FILE *file)
{
    Trie       *trie;

    trie = (Trie *) malloc (sizeof (Trie));
    if (!trie)
        return NULL;

    if (NULL == (trie->alpha_map = alpha_map_fread_bin (file)))
        goto exit_trie_created;
    if (NULL == (trie->da   = da_fread (file)))
        goto exit_alpha_map_created;
    if (NULL == (trie->tail = tail_fread (file)))
        goto exit_da_created;

    trie->is_dirty = FALSE;
    return trie;

exit_da_created:
    da_free (trie->da);
exit_alpha_map_created:
    alpha_map_free (trie->alpha_map);
exit_trie_created:
    free (trie);
    return NULL;
}

通过alpha_map_fread_bin方法读取二进制文件到trie->alpha_map

AlphaMap *
alpha_map_fread_bin (FILE *file)
{
    long        save_pos;
    uint32      sig;
    int32       total, i;
    AlphaMap   *alpha_map;

    /* check signature */
    save_pos = ftell (file);
    if (!file_read_int32 (file, (int32 *) &sig) || ALPHAMAP_SIGNATURE != sig)
        goto exit_file_read;

    if (NULL == (alpha_map = alpha_map_new ()))
        goto exit_file_read;

    /* read number of ranges */
    if (!file_read_int32 (file, &total))
        goto exit_map_created;

    /* read character ranges */
    for (i = 0; i < total; i++) {
        int32   b, e;

        if (!file_read_int32 (file, &b) || !file_read_int32 (file, &e))
            goto exit_map_created;
        alpha_map_add_range (alpha_map, b, e);
    }

    return alpha_map;

exit_map_created:
    alpha_map_free (alpha_map);
exit_file_read:
    fseek (file, save_pos, SEEK_SET);
    return NULL;
}

Bool
file_read_int32 (FILE *file, int32 *o_val)
{
    unsigned char   buff[4];

    if (fread (buff, 4, 1, file) == 1) {
        *o_val = (buff[0] << 24) | (buff[1] << 16) |  (buff[2] << 8) | buff[3];
        return TRUE;
    }

    return FALSE;
}

至此已确定trie_filter_load方法在打开tree文件后读取到内存,因此将trie_filter_load的返回值赋给静态变量,就不用反复打开读取关闭tree文件了,修改后进程恢复正常。


2KB项目(www.2kb.com,软件服务网),提供担保交易、源码交易、虚拟商品、任务交易、网站设计、软件设计、站长交易、域名交易、链接交换、网站交易、广告交易、站长培训、建站美工等服务

  • 全部评论(0)
上一篇:已是第一篇内容
下一篇:已是最后一篇内容
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部