2017-03-07 34 views
0

我初學C和有一個簡單的問題:如何調用子功能只有一次內的週期性函數調用

我有一個函數myfunction的()這是定期調用每100毫秒。 在這個功能我有在的MyFunction初學者()第一次調用來調用其他的功能,但只有一次,但沒有周期性。

void myfunction() // function is called periodically every 100 ms 
{ 
    ... 
    mySubfunction(); // this function have to be called only once in the first call of myFunction() and than skipped each time after that. 
} ... 

如何在c中實現這一點?

+0

如果'mySubfunction'一般不應該在調用myfunction'時被調用,那麼'mySubfunction'不應該是'myfunction'的一部分! – mkrieger1

回答

4

使用static?沿的

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

可變once的示例中的行的東西將被一次initalized並保留其由於static關鍵字調用之間的值。

注意在多線程環境的影響,請參閱this question

0

你可以像

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

...

上先看看任務
0

是非常簡單的,可下面的代碼:

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

這給予100%保證subfunc()即使在幾個併發線程中調用你的func()

將被調用一次且僅一次210

但什麼是如果// some code依靠的subfunc結果呢?在這種情況下,任務已經變得不平凡。需要一些同步。這裏已經取決於操作系統或編譯器。在Windows中,從Vista開始理解這個問題,並添加功能InitOnceExecuteOnce - 讀Using One-Time Initialization 如果您subfunc()在沒有參數的代碼可以是非常簡單的:

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內部調用特殊功能_Init_thread_header_Init_thread_footer(在CRT實現) - 實現,可看在CRT源代碼 - thread_safe_statics.cpp

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; 
}