c - 快速调用短函数中动态内存请求的最佳方式

标签 c multithreading memory-management dynamic-memory-allocation

我正在使用 C 和 FCGI 编写一个动态网站,该网站将在多个线程中运行(由 clang 3.1 编译)。

我为每个基础 HTML 页面都有一个自己的函数。 在其中一些内部,他们分配了一些迷你 Sprite ,例如构建随机生成的 map 。

现在,当我要请求页面的内存时,该页面将在函数结束时触发到标准输出,并且在下次调用之前不再需要内存。

我的第一个想法是简单地声明一个自动指针并这样做:

Sprite *Identifier = malloc (CURRENT_SPRITES * SIZE_OFSPRITE);
/*...*/
free (Identifier);

但是,当每个线程页面被访问数千次时,这会极大地减慢服务器速度,不是吗?

所以我的下一个想法是,当我知道我希望我的服务器支持的最大 Sprite 数量时,我可以这样做:

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,并且处于函数作用域中,因此我可以使用可变长度数组。

但我以前从未真正使用过它,而且我不知道在堆栈上分配此类数组所花费的时间与我其他想法所花费的时间相比是多少。

是否有人可以向我指出这种请求内存的方法的优点和缺点,并给我提示什么可能是适合我的情况的最佳方法(或者可能是不同的方法)?

最佳答案

如果你用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 本地变量的生命周期与线程相同。因此,您可以分配一次并重复使用多次,从而节省分配(取消)分配的时间。此外,由于不同的线程拥有线程局部变量的不同副本,因此不需要互斥锁(解锁)来防止数据竞争。因此,线程效率还是很高的。

在堆栈上分配变量是最简单的。但是正如您所说,堆栈大小是有限的。此外,每次调用都对同一字符串一次又一次地调用 strlen() 看起来并不是一个好主意。

关于c - 快速调用短函数中动态内存请求的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22018527/

相关文章:

c - 查找字符串中最长单词的长度。 C语言

c - 我该如何修复我的代码?我认为问题是第一个scanf?

C++11 thread::id 表示无线程的特殊值

c# - 你如何将一个对象放在另一个线程中?

c++ - 原子int集合的线程安全

c++ - 如何正确使用 std::shared_from_this 或绕过它?

c - 使用虚拟 shell 时,如何检测用户是否在程序和参数后输入 '&'?

c - 为什么这个程序中的scanf()获取不到输入?

c# - 缓冲存储器分配

c# - 如何根据 C++ 在同一内存位置重新初始化 C# 中的对象(或者它是自动完成的)?