我觀察到一個日誌文件的東西,我無法解釋:執行流程 - 可能在退出前兩次輸入功能?
項目的所有代碼被ANSI C,32位exe文件在Windows 7 64位
運行我have類似這樣的工人功能在一個單線程程序運行時,不使用遞歸。在調試過程中記錄被包括,如下所示:
//This function is called from an event handler
//triggered by a UI timer similar in concept to
//C# `Timer.OnTick` or C++ Timer::OnTick
//with tick period set to a shorter duration
//than this worker function sometimes requires
int LoadState(int state)
{
WriteToLog("Entering ->"); //first call in
//...
//Some additional code - varies in execution time, but typically ~100ms.
//...
WriteToLog("Leaving <-");//second to last call out
return 0;
}
上面的函數是從我們的實際代碼簡化但是足以用於說明問題。
我們有時看到的日誌條目,如本:
凡時間/日期郵票是在左邊,然後消息,最後一個字段是時間在clock()
調用日誌功能之間的滴答聲。此日誌記錄表明該函數在退出之前已連續輸入兩次。
沒有遞歸,在單線程程序,它是如何(或是)可能執行流程可以兩次進入功能,完成了第一次調用之前?
編輯:(顯示日誌功能的頂部調用)
int WriteToLog(char* str)
{
FILE* log;
char *tmStr;
ssize_t size;
char pn[MAX_PATHNAME_LEN];
char path[MAX_PATHNAME_LEN], base[50], ext[5];
char LocationKeep[MAX_PATHNAME_LEN];
static unsigned long long index = 0;
if(str)
{
if(FileExists(LOGFILE, &size))
{
strcpy(pn,LOGFILE);
ManageLogs(pn, LOGSIZE);
tmStr = calloc(25, sizeof(char));
log = fopen(LOGFILE, "a+");
if (log == NULL)
{
free(tmStr);
return -1;
}
//fprintf(log, "%10llu %s: %s - %d\n", index++, GetTimeString(tmStr), str, GetClockCycles());
fprintf(log, "%s: %s - %d\n", GetTimeString(tmStr), str, GetClockCycles());
//fprintf(log, "%s: %s\n", GetTimeString(tmStr), str);
fclose(log);
free(tmStr);
}
else
{
strcpy(LocationKeep, LOGFILE);
GetFileParts(LocationKeep, path, base, ext);
CheckAndOrCreateDirectories(path);
tmStr = calloc(25, sizeof(char));
log = fopen(LOGFILE, "a+");
if (log == NULL)
{
free(tmStr);
return -1;
}
fprintf(log, "%s: %s - %d\n", GetTimeString(tmStr), str, GetClockCycles());
//fprintf(log, "%s: %s\n", GetTimeString(tmStr), str);
fclose(log);
free(tmStr);
}
}
return 0;
}
你是如何確認只有一個線程的?特別是,你如何知道UI定時器沒有創建一個單獨的上下文來執行回調? – jxh
@jxh - 在我使用的環境有定時器在主線程中運行的UI定時器,還有其他選項,例如AsyncTimer,它創建了自己的線程,但在這種情況下,我只使用UI定時器 – ryyker
關於快速執行代碼,有時候輸出流可能會失序,在每次寫入之後嘗試fflush(stdout)(或者發送輸出的時候),看看實際發生了什麼。 –