第一件事是第一件事。把一些額外的代碼也打印出當前時間,而不是依靠launchd
來做到這一點。
標準輸出的不同沖洗行爲有可能發揮作用。
如果標準輸出可以被確定爲交互式設備(例如從命令行運行它),它是行緩衝 - 您將在延遲之前刷新「之前」行。
否則,它的全緩衝,以便沖洗可能不會發生,直到程序退出(或到達的緩衝區大小(例如)4K。這意味着,launchd
可以看到線一起出來,既後延時
獲取C代碼時間戳行會告訴你,如果部份是問題,是這樣的:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while((delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
return 0;
}
明白爲什麼緩衝可能是一個問題,請考慮運行上面進行如下的程序:
pax> ./testprog | while read; do echo $(date): $REPLY; done
Tue Jan 31 12:59:24 WAST 2012: 1327985961: Before delay
Tue Jan 31 12:59:24 WAST 2012: 1327985964: After delay
可以看到的是,因爲緩衝導致兩個線當程序退出,他們得到的12:59:24
的同一時刻,儘管他們產生相距三秒鐘程序中的事實出現在while
循環。
事實上,如果你改變它,如下所示:
pax> ./testprog | while read; do echo $(date) $REPLY; sleep 10 ; done
Tue Jan 31 13:03:17 WAST 2012 1327986194: Before delay
Tue Jan 31 13:03:27 WAST 2012 1327986197: After delay
你可以看到由「周邊」節目看到的時間(while
循環或,你的情況,launchd
)是從完全斷開程序本身)。
其次,usleep
是一個功能,可以失敗!它可以通過返回-1,這是非常不大於零而失敗。
這意味着,如果它失敗了,你的延遲就沒有效果。
的Single UNIX Specification狀態,爲usleep
:
成功完成,usleep()函式返回0。否則,它返回-1,並設置errno以指示錯誤。
如果出現以下情況,usleep()函數可能會失敗:[EINVAL]:指定的時間間隔爲1,000,000或更多微秒。
這肯定與你的代碼的情況下,雖然這將是很難解釋爲什麼它之後開機,而不是之前的作品。
有趣的是,Mac OSX文檔沒有列出EINVAL,但他們做允許EINTR,如果睡眠被外部中斷。再一次,你應該檢查一下。
您可以檢查這些可能性的東西,如:
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while((delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
printf("Delay became %d, errno is %d\n", delay, errno);
}
還有一件事我剛剛注意到,從你的代碼中似乎假設微秒unslept的usleep
收益數量(剩餘),然後循環直到全部完成,但該行爲不會被手冊頁承載。
我知道nanosleep
這樣做(通過更新傳遞的結構來包含剩餘時間而不是返回它),但usleep
只返回0或-1。
sleep
函數以這種方式工作,返回秒數。如果可能的話,也許你可以考慮使用這個函數。
在任何情況下,我仍然會運行上面的(上一個)代碼段,以便確定實際問題是什麼。
你想通過延遲代碼執行來實現什麼? – Costique 2012-01-31 04:51:31
@Costique我在等待各種服務不僅可用,而且還執行了一些我無法測試的具體操作。此外,這個守護進程必須通過雪豹在老虎上運行,並且每種情況下的服務都略有不同 - 我想避免添加額外的代碼來檢查平臺。簡單的延遲可能被認爲是破解,但它是一個優雅的延遲,它可以解決我在所有平臺上的問題,而不會影響程序的整體運行。 – 2012-01-31 06:01:40