如何在周期性函数调用中只调用一次子函数

时间:2017-03-07 12:02:24

标签: c

我是初学者,有一个简单的问题:

我有一个函数 myfunction(),每100毫秒定期调用一次。 在这个函数中,我必须在 myfunction()的beginn第一次调用时调用另一个函数,但是不能定期调用。

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [nl.insiteweb.acc.Application]; nested exception is java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
    at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:520) ~[testproject.jar:na]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:184) ~[testproject.jar:na]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[testproject.jar:na]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[testproject.jar:na]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[testproject.jar:na]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[testproject.jar:na]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686) ~[testproject.jar:na]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524) ~[testproject.jar:na]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[testproject.jar:na]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [testproject.jar:na]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [testproject.jar:na]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [testproject.jar:na]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [testproject.jar:na]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [testproject.jar:na]
    at nl.insiteweb.acc.Application.main(Application.java:16) [testproject.jar:na]
Caused by: java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
    at org.springframework.util.Assert.notEmpty(Assert.java:276) ~[testproject.jar:na]
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations(AutoConfigurationImportSelector.java:152) ~[testproject.jar:na]
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports(AutoConfigurationImportSelector.java:94) ~[testproject.jar:na]
    at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:512) ~[testproject.jar:na]
    ... 14 common frames omitted

如何在c中实现这一点?

4 个答案:

答案 0 :(得分:4)

使用static

的内容
void myfunction() // function is called periodically every 100 ms
{
    static int once = 1;
    if (once) {
        mySubfunction(); 
        once = 0;
    }
}  

示例中的变量once只会被初始化一次,并且由于static关键字而在调用之间保留其值。

请注意多线程环境中的含义,请参阅this question

答案 1 :(得分:0)

你可以拥有像

这样的东西
static int flag = 1
void myfunction() // function is called periodically every 100 ms
{
    if(flag)
    {
       mySubfunction(); 
       flag = 0;
    }     
 }   

...

答案 2 :(得分:0)

首先看看任务很简单,可以是下一个代码:

void func()
{
    static LONG first = TRUE;
    if (_InterlockedExchange(&first, FALSE))
    {
        subfunc();
    }
    // some code
}

这样可以100%保证subfunc()只会被调用一次,即使多个线程同时调用你的func()

但如果// some code取决于subfunc的结果会怎样?在这种情况下,任务变得非常微不足道。需要一些同步。这里已经依赖于os或编译器。在Windows中,从Vista开始了解此问题并添加功能InitOnceExecuteOnce - 阅读Using One-Time Initialization 如果您的subfunc() 中没有 out 参数代码可以非常简单:

BOOL CALLBACK InitOnceCallback(PINIT_ONCE /*InitOnce*/, PVOID /*Parameter*/,PVOID* /*Context*/)
{
    subfunc();
    return TRUE;
}

void func()
{
    static INIT_ONCE once = RTL_RUN_ONCE_INIT;
    if (InitOnceExecuteOnce(&once, InitOnceCallback, 0, 0))
    {
        // somecode
    }
    // error init
}

也有一些现代编译器可以纠正句柄静态一次初始化。说CL的最新版本。用它代码可以是下一个:

void func()
{
    static char tag = (subfunc(), 0);
    // some code
}

此处CL内部调用特殊函数(在 CRT 中实现)_Init_thread_header_Init_thread_footer - 实现可以查看crt源代码 - {{1} }

答案 3 :(得分:0)

这可能比您正在寻找的更高级,但您可以使用函数指针并更改调用哪个函数。

// Function declarations
void mySubfunction(void);
void myNormalfunction(void);

// Function pointer, which can be changed at run time.
static void (*myfunction)(void) = mySubfunction;

void mySubfunction(void)
{
    // Do the sub-function stuff.

    // Change the function pointer to the normal function.
    myfunction = myNormalfunction();

    // Do the normal function stuff (if necessary on the first call).
    myNormalfunction();
}

void myNormalfunction(void)
{
    // Etc.
}

int main(void)
{
    int x;
    for(x = 0; x < 3; x++)
    {
        // Call myfunction as you usually would.
        myfunction();
    }
    return 0;
}