0

tl; dr:我如何配置cJSON以在子进程中分配内存,以便父进程可以看到生成的结构?


我有一个请求,其中列出了要为其生成摘要并以 JSON 形式返回的多个产品。目前,我的代码是单线程的,并使用 cJSON 库来组合和编组 JSON。

由于摘要的计算成本很高(用户请求将某些计算作为摘要的一部分执行),我想fork(2)为每个请求的产品,然后让它获取、处理和总结cJSON_Object(从技术上讲cJSON*,但“构造函数”是cJSON_CreateObject) ,然后让父线程等待所有子线程返回他们的cJSON_Object对象以连接在一起,执行一些后期处理,最后编组为一个字符串返回。由于后处理,我想返回父 acJSON_Object而不是让子线程返回字符串。

现在,我看到cJSON.h:144 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)which 接受cJSON.h:125 struct internal_hooks允许您指定自定义malloc()free()实现...如果我能找到分配共享内存的版本...并共享相同类型,那将是非常好的。我找到的最接近的是shmalloc/shfree但这来自OpenMPI库,对于看起来应该是简单的工作线程的东西来说似乎有点矫枉过正......

现在,这就是我卡住的地方如何将 cJSON 结构图从子进程返回到父进程

我附上了我认为最好的(尽管未经测试的)解决方案,作为不进一步混淆这个问题的答案。

PS - 最好该解决方案将自身限制为 POSIX API,但仅限 Linux 是可以接受的,并且作为最后的手段使用附加库。

4

2 回答 2

0

我还没有测试过这个,它看起来很hackish,但这是我迄今为止想到的最好的:

我确实找到了shmget(3)。类型签名不兼容,所以我想我可以包装它。在每个孩子中,我可以生成一个唯一的整数用作key_t,并分配足够的内存来包含响应。然后提供我自己的malloc(),它只是从shmget. 最后,通过调用返回key_t给父级。exit(3)父线程将获得key_tfrom的值wait(3),然后能够获取cJSON_Object并将其与其他片段组合。

所以答案是让 on child 开始:shmget一些内存,然后编写一个malloc()-compatible 函数my_malloc()来分配该shmgeted 内存,并有一个指针my_malloc()传递给 cJSON_InitHooksvia struct internal_hooks

于 2019-01-29T15:17:44.873 回答
0

不幸的是,这并不像在共享内存段中分配一些对象那么简单。cJSONobject 是一个链接的数据结构,考虑到 JSON 对象可以由嵌套列表和哈希组成,这并不奇怪。

typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;
    ...
}

这种结构指针,并将指针存储在共享内存区域内可能不是一个好主意。每个进程都有自己的虚拟内存空间,共享内存段可能不会在两个进程中映射到相同的地址。如果是这种情况,相同的指针值将指向一个地址空间中的有效对象,但在其他地址空间中它可能指向垃圾。

于 2019-01-29T15:29:43.847 回答