C 如何检查此函数是从哪个文件调用的?
看,我有一个库,它有两个api let调用C 如何检查此函数是从哪个文件调用的?,c,C,看,我有一个库,它有两个api let调用 api1() 及 现在api2在内部也调用api1 所以在一种情况下我想做的是 当其他应用程序调用api1()时,请执行一些特殊工作 但是当api2()调用api1()时,就不要做那种特殊的工作 我该怎么做 有没有办法让我知道api1()是从库本身而不是从应用程序调用的 编辑: api1() { sem_wait(); // this create deadlock // do some task sem_post(); } 现在a
api1()
及
现在api2在内部也调用api1
所以在一种情况下我想做的是
- 当其他应用程序调用api1()时,请执行一些特殊工作
- 但是当api2()调用api1()时,就不要做那种特殊的工作
api1()
{
sem_wait(); // this create deadlock
// do some task
sem_post();
}
现在api2()是这样的
api2()
{
sem_wait();
api1();
sem_post();
}
查看我的两个函数…当应用程序调用api1()时,我需要在sem_wait和sem_post中工作,但当api2()调用api1()时,我不想再次执行sem_wait,因为它会产生死锁
我需要一些机制,以便api1()检查它是否是从api2()调用的,然后不要使用sem\u wait和sem\u post这不容易通过内省实现。您可以调查调用堆栈,但这是非常不可移植的,因此不建议这样做 处理这个问题的一种方法是传递一个参数来控制行为的变化。这还有一个好处,就是使函数的行为更加透明和明确。正如@blueshift所指出的,这会给外部呼叫者带来负担。将函数分为两个版本,一个供内部使用,一个供外部使用,可以减轻这一负担
根据你的编辑,我认为这个设计有点不合适。同步职责应该是职能部门内部的,也可以是外部的。将这种责任有时是内部的,有时是外部的,这是非常危险的。这将是解决问题的一种方法。另一种解决方法是使用递归锁。这不容易通过内省实现。您可以调查调用堆栈,但这是非常不可移植的,因此不建议这样做 处理这个问题的一种方法是传递一个参数来控制行为的变化。这还有一个好处,就是使函数的行为更加透明和明确。正如@blueshift所指出的,这会给外部呼叫者带来负担。将函数分为两个版本,一个供内部使用,一个供外部使用,可以减轻这一负担
根据你的编辑,我认为这个设计有点不合适。同步职责应该是职能部门内部的,也可以是外部的。将这种责任有时是内部的,有时是外部的,这是非常危险的。这将是解决问题的一种方法。另一种解决方法是使用递归锁。对于两个不同的作业(+special work和-special work),需要两个不同的函数调用(函数名或参数)。上下文敏感函数不仅不受C支持,而且绝对有害,因为它们增加了整个Chomsky的复杂性。对于两个不同的作业(+special work)和-special work),您需要两个不同的函数调用(函数名或参数)。上下文敏感函数不仅不受C支持,而且绝对有害,因为它们增加了整个Chomsky的复杂性。您可以构建库,以便
api2()
告诉api1()
它是调用方。从外部调用时,api1()
会看到一个未知的调用方。您可以构建库,以便api2()
告诉api1()
它就是调用方。从外部调用时,api1()
会看到一个未知的调用方。通常会执行以下操作:
// internal function
static int api1_internal(void) {
do stuff assuming the lock is held;
}
// function for external callers, doing extra locking
int api1(void) {
int ret;
lock();
ret = api1_internal();
unlock();
return ret;
}
// some internal function using internal api1
void internalfunc(void) {
lock();
do some things();
api1_internal();
unlock();
}
注意:api1_internal被声明为static,以停止使用它的文件之外的任何内容
如果你真的想弄糊涂,你可以先定义api1(),然后用类似
#define api1 api1_internal
这将使您的代码保持美观,但稍后会让您感到困惑。不要那样做
通常在函数的内部非锁定版本中使用前导下划线,因此
static int _api1(void)
经常这样做:
// internal function
static int api1_internal(void) {
do stuff assuming the lock is held;
}
// function for external callers, doing extra locking
int api1(void) {
int ret;
lock();
ret = api1_internal();
unlock();
return ret;
}
// some internal function using internal api1
void internalfunc(void) {
lock();
do some things();
api1_internal();
unlock();
}
注意:api1_internal被声明为static,以停止使用它的文件之外的任何内容
如果你真的想弄糊涂,你可以先定义api1(),然后用类似
#define api1 api1_internal
这将使您的代码保持美观,但稍后会让您感到困惑。不要那样做
通常在函数的内部非锁定版本中使用前导下划线,因此
static int _api1(void)
为什么你会让一个函数做两件不同的事情,这取决于调用它的人是谁;从这些编辑来看,我先前对原始问题的回答是合理的,但这是危险的,因此我删除了它。为什么要让函数做两件不同的事情,取决于调用它的人?编辑极大地改变了问题的上下文;鉴于这些编辑,我先前对原始问题的回答是合理的,这是危险的,因此我将其删除。如果这意味着所有外部调用方都必须传递一个始终为“external”的额外参数,那就不好了。如果他们有不同的设置,就会中断。@blueshift是的,你的方法会很有效。我没有想到用两个不同的函数来解决这个问题。我只是偷了Linux内核中各种东西的方法:)站在巨人的肩膀上。如果这意味着所有外部调用方都必须传递一个额外的参数,而这个参数总是“外部的”,那就不好了。如果他们有不同的设置,就会中断。@blueshift是的,你的方法会很有效。我没有想到用两个不同的函数来解决这个问题。我只是在Linux内核中偷了很多东西:)站在巨人的肩膀上。