如何使用POSIX通过进程父级返回cJSON片段?

时间:2019-01-29 15:17:45

标签: c posix shared-memory worker cjson

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


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

由于摘要的计算量很大(用户要求将某些计算作为摘要的一部分进行),因此我想为每个请求的产品fork(2),然后将其获取,处理并汇总为{ {1}}(从技术上来说cJSON_Object,但“构造函数”是cJSON_CreateObject),然后have the parent thread wait for all children to return将其cJSON*对象结合在一起,执行一些后处理,最后编成字符串返回。由于进行了后期处理,我想将cJSON_Object返回到父级,而不是让子线程返回字符串。

现在,我看到cJSON.h:144 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)接受了一个cJSON.h:125 struct internal_hooks,它允许您指定自定义cJSON_Objectmalloc()的实现...如果我能找到一个实现的话,那会很麻烦分配共享内存...并共享相同类型的版本。我找到的最接近的是shmalloc/shfree,但这是来自OpenMPI库的,对于似乎应该是简单的工作线程来说似乎有点过头了……

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

  

我附上了我认为最好的(尽管未经测试)解决方案,以解决这个问题。

PS-优选地,该解决方案将其自身限制于POSIX API,但仅Linux是可接受的,并且不得已使用其他库。

2 个答案:

答案 0 :(得分:0)

我还没有测试过,这似乎有点黑,但这是我到目前为止所想到的最好的:

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

因此答案将是让子启动:shmget的一些内存,然后编写一个malloc()兼容的函数my_malloc(),该函数从该shmget分配内存内存,并具有指向my_malloc()的指针,该指针通过cJSON_InitHooks传递给struct internal_hooks

答案 1 :(得分:0)

不幸的是,它并不像在共享内存段中分配一些对象那样简单。 cJSON对象是一个链接的数据结构,考虑到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;
    ...
}

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