我正在用C和FCGI编写一个动态网站,它将在多个线程中运行(由clang 3.1编译)。
我为每个基础HTML页面都有自己的功能。 在其中一些内部,他们正在分配一些迷你精灵,例如构建一个随机生成的地图。
现在,当我要为该页面的内存请求时,该函数将在函数结束时触发到stdout,并且在下次调用之前不再需要内存。
我的第一个想法是简单地声明一个自动指针并按照这样做:
Sprite *Identifier = malloc (CURRENT_SPRITES * SIZE_OFSPRITE);
/*...*/
free (Identifier);
但是当每个线程要访问该页面数千次时,这会大大减慢服务器的速度,不是吗?
所以我的下一个想法是,因为我知道我希望服务器支持的最大精灵数量,我可以这样做:
Sprite Identifier[MAX_SPIRTES_PER_MAP];
/*...*/
但是当我考虑到堆叠内存的数量时,这只是一种痛苦。
所以我想的是:
static inttype DynamicCurrentAmount = 0;
static Sprite *Identifier;
somethreadsafingmutexfunctionLOCK();
if (DynamicCurrentAmount == 0)
{
Identifier = malloc (ParamRecivedByFunctionCall* sizeof (Sprite));
ReturnValCheck(Identifier);
}
if (DynamicMaxAmount < ParamRecivedByFunctionCall)
{
DynamicMaxAmount = ParamRecivedByFunctionCall;
Identifier = realloc (Identifier, ParamRecivedByFunctionCall* sizeof (Sprite));
ReturnValCheck(Identifier);
}
somethreadsafingmutexfunctionUNLOCK();
但是这种方式的缺点是,每次只有1个客户端可以通过他的线程获得HTML页面。 另外我不确定,在哪种情况下锁定/解锁甚至可以花费更多时间作为简单的内存分配?
我的最后一个也许是最可能的想法就是这个:
Sprite Identifier[(strlen ("some HTML stuff per Sprite in map")) * ParamRecivedByFunction) + strlen ("htmlbased sprite map table torso")];
由于我是纯C99并且没有使用VisualC而且我在函数范围内,所以我可以使用可变长度数组。
但我以前从来没有真正使用它,而且我不知道是否需要花时间在堆栈上分配这样的数组与我的其他想法相关的时间。
有谁能指出这种请求我记忆的方法的优点和缺点,并给我一个暗示,对我的情况可能是最好的方式(或者可能是另一种方式)?
答案 0 :(得分:0)
如果您使用GCC编译程序,则可以使用thread-local storage。
static __thread Sprite* Identifier = malloc(CURRENT_SPRITES * SIZE_OFSPRITE);
/* Clear Identifier's content */
/* ... */
/* Do not free it. Just reuse it at the next function call. */
通过线程本地存储,static __thread
局部变量的生命周期与线程相同。因此,您可以分配一次并重复使用多次,以便节省(de)分配的时间。此外,由于不同的线程拥有线程局部变量的不同副本,因此您不需要互斥锁(un)来防止数据争用。因此,线程效率仍然很高。
在堆栈上分配变量是最简单的。但是正如你所说,堆栈大小是有限的。另外,每次通话一次又一次地为同一个字符串调用strlen()
并不是一个好主意。