【问题标题】:shmop_open what is the key parameter?shmop_open 的关键参数是什么?
【发布时间】:2015-10-18 12:31:22
【问题描述】:

来自 PHP,它说

int shmop_open (int $key, string $flags, int $mode, int $size)

$key 在哪里

共享内存块的系统 ID。可以作为十进制或十六进制传递。

有些人用任意数字(1) 填充$key,而另一些人使用文件来获取$key 值(2)。 $key 是随机值吗?

(1)

   $shm_id = shmop_open(987654, "c", 0644, 100);

(2)

   $shm_key = ftok(__FILE__, 't');
   $shm_id = shmop_open($shm_key, "c", 0644, 100);

顺便说一句,在 Windows 中,我使用了一个小数字,虽然它有效,但我最多只能使用 1024 个字节。在使用大数字作为密钥时,我能够处理更多内存。为什么?

【问题讨论】:

    标签: php windows shared-memory


    【解决方案1】:

    如果您查看source of shmop_open(),您会发现该函数基本上是POSIX shmget()shmctl()shmat() 例程的包装器。您可以看到shmop_open()$key 参数作为System V IPC 密钥传递给shmget()

    shmget() 返回与给定键关联的共享内存段的标识符。如果传递给shmget() 的键是特殊值IPC_PRIVATE,那么这是指一个唯一的共享内存段,只能由fork() 创建的后代进程继承(注意这可能与您的情况无关) .否则,为了让两个进程访问同一个共享内存段,它们需要使用相同的键来获取该段的标识符。

    您可以使用固定键,就像您引用的第一个示例一样。但是,使用固定键容易发生意外冲突。

    更好的方法是使用ftok()。如果您始终使用ftok() 生成密钥,那么由于ftok() 保证生成的密钥在使用不同的 id 值或命名两个不同文件的路径时会有所不同,因此发生冲突的风险会降低同时存在于同一个文件系统上。

    How to choose the "Key" for inter-processes communication in Linux?

    Windows 上的 PHP 本身并不支持共享内存函数。相反,它们是通过“线程安全资源管理器”(TSRM)模拟的。您可以在TSRM/tsrm_win32.c 中找到the TSRM implementation of shmget()。众所周知,TSRM 共享内存仿真有些古怪(例如,请参阅 this answer)。

    我觉得奇怪的一件事是 TSRM shmget() 实现通过以下方式构造了一个表示共享内存段的 Windows 文件映射名称:

    char shm_segment[26], shm_info[29];
    /* ... */
    snprintf(shm_segment, sizeof(shm_segment)-1, "TSRM_SHM_SEGMENT:%d", key);
    

    因为 "TSRM_SHM_SEGMENT:" 的长度为 17,而对 snprintf() 的调用最多将写入 24 个字符,因此密钥只剩下 7 个字符。因此,似乎只有介于 -999999 和 9999999 之间的键才能在 Windows 上与 PHP 一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 2020-02-07
      • 2016-04-10
      • 2012-09-29
      • 1970-01-01
      相关资源
      最近更新 更多