C 如何检查函数是否正在回调自身
假设我们在库中有一个C函数funA,在funA中它会调用一些其他函数funB,funC等等。funB和funC可能会给funA回电话。因此,问题是: 是否有可能在funA内部检测到这种情况,比如:C 如何检查函数是否正在回调自身,c,recursion,computer-science,cpu-architecture,software-design,C,Recursion,Computer Science,Cpu Architecture,Software Design,假设我们在库中有一个C函数funA,在funA中它会调用一些其他函数funB,funC等等。funB和funC可能会给funA回电话。因此,问题是: 是否有可能在funA内部检测到这种情况,比如: void funA(void) { if (...) { // Calling back to funA } } 结论 在单线程环境中,静态/全局变量可以工作 在多线程环境中,必须依赖TLS支持 没有任何答案可以通过语言(C)级技巧实现这一点 如果只是一次调用,
void funA(void) {
if (...) {
// Calling back to funA
}
}
结论
- 在单线程环境中,静态/全局变量可以工作
- 在多线程环境中,必须依赖TLS支持
- 没有任何答案可以通过语言(C)级技巧实现这一点
void funA(void) {
static bool used = false;
if (used)
{
printf("It is used!\n");
}
used = true;
// .... Do stuff here, including possible recursion
used = false;
}
注意-这不适用于多线程-此函数不可重入。这可以使用静态标志完成 调用函数时,如果未设置该标志,则设置该标志并继续,否则立即返回。然后在函数结束时,清除该标志,以便再次输入
void funcA(void)
{
static int callback = 0;
if (callback) return;
callback = 1;
...
callback = 0;
}
如果这需要在多个线程中单独工作,您可以将变量声明为
\u thread\u local
而不是static
,使用间接级别,您甚至可以计算调用函数的次数:
void func( int count )
{
printf( "Count is %d\n", count );
if ( ... ) // no longer want to recurse...
{
return;
}
func( count + 1 );
}
// wrap the actual recursive call to hide the parameter
void funA()
{
func( 0 );
}
这样,它是完全线程安全的。如果不希望传递包装函数或参数,可以使用。也许可以使用另一种方法来识别调用方:
void func_a(void *ptr);
void func_b(void);
void func_c(void);
void func_a(void *caller)
{
if(caller == func_a)
{
printf("called from func_a\n");
return;
}
if(caller == func_b)
{
printf("called from func_b\n");
return;
}
if(caller == func_c)
{
printf("called from func_c\n");
return;
}
if(caller == NULL)
{
printf("called from somewhere elese - going to call myself\n");
func_a(func_a);
}
}
void func_b()
{
func_a(func_b);
}
void func_c()
{
func_a(func_c);
}
int main()
{
func_b();
func_c();
func_a(NULL);
return 0;
}
是的,通过使用静态标志。在函数开始时检查它,设置它,然后在函数返回之前清除它。@不能工作的风向标funA可能会被不同的线程调用,是吗?然后请把这一要求放在问题中。已经有一些库函数不是线程安全的。为什么不让它包含一个参数呢?@mnistic您能解释一下它是什么样子吗?我想这可能是最好的答案了。谢谢@dbush