0

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

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

,这取决于某些参数的值param。参数param由函数计算,例如

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

我们希望param尽可能地向调用者隐藏(类型、大小、值...)的详细信息,其中调用者是一个使用函数compute_paramneeds_param. 如果您可以自由修改needs_param和,如何最有效和线程安全地实现这一点compute_param

我考虑并排除了以下可能性:

答:因为我们可以自由修改needs_param,所以一种方法是传递gen_param及其参数而不是param,并让needs_param计算param自行计算。但是param计算起来很昂贵,并且需要多次作为其他函数的参数。

b:我们可以实现compute_param

void * compute_param (...) {
    static param_type param = ...
    return &param;
}

但是,这不是线程安全的,使用openmp我们必须保护调用

#pragama omp critical
{
    void * param = compute_param (...)
}

这将严重影响线程程序的性能。

C:一种解决方案是使用 malloc/free

void compute_param (..., void * param) {
    param = malloc (sizeof (param_type));
    ....
    *param = ...
}   

这给调用者带来了释放分配的内存的负担,同时由于昂贵的堆内存而效率低下。

d:的使用alloca,例如

void * param = alloca (param_size);
compute_param (..., param);
...
needs_param (param, ...);

,需要有关param调用者空间中大小的信息,我们希望将其隐藏。

你有什么建议吗?

4

1 回答 1

3

我建议您使用称为“不透明指针”的解决方案。例如,它在 Windows 内核世界中被广泛用于向调用者隐藏对象。

您首先定义一个指针类型,如typedef void* pobject;.

然后,您只能在程序中以这种方式操作您的对象。一堆函数,如pobject create_object(),use_object(pobject)free_object(pobject)使用这种技术。

为确保可以安全地操作您的对象,请在对象本身中添加一个互斥锁。您还可以将对象的大小添加为第一个成员,以快速检查对象的性质(是否被其他人操作过?)。

然后,在函数中,您真正定义您的对象,如typedef struct { } object_int, *pobject_int. 在每个操作它的函数中,只需将你的不透明指针pobjectpobject_int.

它确实迫使您使用堆,但如果您不想与调用者共享有关您的对象的任何信息,这是最合适的解决方案。

于 2013-01-16T10:49:14.797 回答