代码之家  ›  专栏  ›  技术社区  ›  Will Brian Hodge

从共享内存中检索时,PHP是否复制变量?

  •  4
  • Will Brian Hodge  · 技术社区  · 15 年前

    如果我运行shm_get_var(),它会返回一个“引用”,将数据保存在共享内存中吗?

    我希望在共享内存中保留一个大约50MB大小的数组,这样它就可以被多个进程使用,而不必保留50MB数组的多个副本。如果共享内存不是答案,有人有其他想法吗?

    4 回复  |  直到 12 年前
        1
  •  6
  •   SpamapS    15 年前

    这是php 5.2.9中sysvsem.c的相关C代码片段:

    /* setup string-variable and serialize */
    /* get serialized variable from shared memory */
    shm_varpos = php_check_shm_data((shm_list_ptr->ptr), key);
    
    if (shm_varpos < 0) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable key %ld doesn't exist", key);
        RETURN_FALSE;
    }
    shm_var = (sysvshm_chunk*) ((char *)shm_list_ptr->ptr + shm_varpos);
    shm_data = &shm_var->mem;
    
    PHP_VAR_UNSERIALIZE_INIT(var_hash);
    if (php_var_unserialize(&return_value, (const unsigned char **) &shm_data, shm_data + shm_var->length, &var_hash TSRMLS_CC) != 1) {
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable data in shared memory is corrupted");
        RETURN_FALSE;
    }
    PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
    

    每次调用shm_get时,php都必须取消整个值的序列化,而在50MB数组上,这个过程会非常缓慢。

    把它分解成个人价值观怎么样?

    另外,您可能需要考虑使用APC的变量缓存,它将为您处理所有共享内存和锁定(并且还将使用哈希表进行键查找)。

        2
  •  2
  •   RageZ    15 年前

    形成文件的措辞

    shm_get_var()返回变量 在 给定共享内存段。这个 变量仍存在于 共享内存。

    我会说是的,这是对共享内存空间的引用。

        3
  •  2
  •   Akrikos    12 年前

    我不是这方面的专家,但是否可以为此编写一个类似以下内容的快速测试?

    $key = 1234;
    //put something small into shared memory
    $identifier = shm_attach($key, 1024, 0777);
    shm_put_var($identifier, $key, 'shave and a hair cut');
    
    $firstVar = shm_get_var($identifier, $key);
    $firstVar .= 'Test String of Doom';
    $secondVar = shm_get_var($identifier, $key);
    
    if ($firstVar == $secondVar) {
        echo 'shm_get_var passes by reference';
    } else {
        echo 'shm_get_var passes by value';
    }
    
        4
  •  1
  •   Treby    15 年前

    您可以使用shm_remove()。 看看这个: http://php.net/manual/en/function.shm-remove.php