在C程序中考虑以下情况。我们有一组函数,让泛型函数

 void needs_param (void * param, ...);

,这取决于某些参数的值。参数param由函数计算,例如。
 void compute_param (..., void * param);

我们希望尽可能地向调用方隐藏param(类型、大小、值…)的详细信息,其中调用方是使用函数paramcompute_param的函数。如果您可以自由修改needs_paramneeds_param,如何最有效地实现这一点并保证线程安全?
我考虑并排除了以下可能性:
答:因为我们可以自由修改compute_param,一种方法是传递needs_param及其参数而不是gen_param,让param自己计算needs_param。但是param的计算代价很高,而且它需要多次作为其他函数的参数。
b:我们可以将param作为
void * compute_param (...) {
    static param_type param = ...
    return &param;
}

但是,这不是线程安全的,使用compute_param我们必须保护调用
#pragama omp critical
{
    void * param = compute_param (...)
}

这将严重影响线程程序的性能。
C:一个解决方案将使用malloc/free
void compute_param (..., void * param) {
    param = malloc (sizeof (param_type));
    ....
    *param = ...
}

这给调用者带来了释放分配内存的负担,同时由于堆内存的昂贵而效率低下。
d:使用openmp,例如。
void * param = alloca (param_size);
compute_param (..., param);
...
needs_param (param, ...);

,需要有关调用方空间中alloca大小的信息,我们希望将其隐藏。
你有什么建议吗?

最佳答案

我建议您使用一种称为“不透明指针”的解决方案。例如,它在Windows内核世界中被广泛使用,以隐藏对象,使其不受调用方的影响。
首先定义一个指针类型,如typedef void* pobject;
然后,你只能在程序中那样操作你的对象。许多函数,如pobject create_object()use_object(pobject)free_object(pobject)都使用这种技术。
要确保可以安全地操作对象,请在对象本身中添加互斥对象。您还可以将对象的大小添加为第一个成员,以便快速检查对象的性质(是否被其他人操纵?).
然后,在函数中,您可以像typedef struct { } object_int, *pobject_int那样定义对象。在每个操作它的函数中,只需将不透明指针从pobject投射到pobject_int
它确实迫使您使用堆,但如果您不想与调用方共享有关对象的任何信息,则这是最合适的解决方案。

关于c - 在C中传输隐藏数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14356342/

10-11 23:14