Re: [問題] linux c抓取時間的問題

看板C_and_CPP作者 (藍影)時間12年前 (2011/09/13 19:33), 編輯推噓1(1020)
留言21則, 6人參與, 最新討論串2/3 (看更多)
拋磚引玉。

09/13 16:01,
一般在做排程時,大多都是配合os之 shell/cmd 去做排程
09/13 16:01

09/13 16:02,
windows 是at, linux 記得有 Crontab / atd / at
09/13 16:02

09/13 16:02,
而用 c 寫的那部份,是完全不管時間的..
09/13 16:02

09/13 16:58,
大大因為我的uclinux裡沒有Crontab/atd/at這些指令
09/13 16:58
我見識真的淺了,好奇的是,Crontab / at / atd 沒辦法額外抓執行檔回來用嗎? 怕到時 release 還要附出去的話,就直接再寫個 setup shell,應是較佳的選擇。 若不行的話,再找一下 uclinux 有沒有可以改登錄檔的地方,去自動執行之類的。 上面兩個方案我認為應是較佳的解法,可解決的話, C app 就別搞時間問題; 如果都確定不行的話,再搞以下的東西。 ※ 引述《jimmycch (JimmyChung)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : uClinux 這系統沒碰過, 只提出我覺得程式碼有問題的地方。 : 問題(Question): : 各位大大,小弟因為現在要在linux上寫一個在我要的時間點,把資料寫到txt檔裡,我己經 : 寫好了,但因為我放到設備上時,如果手動啟動我寫的這隻程式,都沒有問題,但如果我加到 : ini檔(開機時,會去自動執行的程式),就會有問題.程式執行到我設的那個時間點時,會進 : 入到zombie的狀態?人家是說我沒有按linux的邏輯下去寫程式才會這樣. zombie 狀態我沒常聽別人提起,只在書上輕描淡寫帶過, 想請教的是,zombie 狀態是不是就和在 windowns 系統上的 「應用程式沒有回應」,要強制關掉,這種情形似? 若是的話,遇過的情形大致上有幾種, 1. 條件判斷沒寫完全; 2. GUI 環境下 while(1) dead loop 進去後,完全沒時間再去取 message 3. 另一是 資源衝突 或 資源饋乏 之情況下產生 (這情況較少見) 4. process 莫名等待一個不會有結果的結果,如卡在 scanf 什麼之類的 這個相信你碰 linux 會比我清楚。 : 以下是我的程式碼,想請問什麼是按linux的邏輯 我是 linux 絕緣體,只能協助抓出程式邏輯問題, 待其他 linux 高人予以更佳之意見。下述截取程式碼重點探討。 : while(1) : { : Sleep(1); 我不知道在 Linux 下, Sleep(1) 指的是 ms 還是 sec, 如果是 ms 的話,總覺得用 1 不是那麼好,何況你一天也只執行一次而已, 沒必要讓系統這麼吃緊。 我習慣是,最小值設略大於 task timeslice, 這個值我只知道它在 windows 系列是多少,不知道在 linux 下是多少, 總之別設太小,太吃資源。 : if( ( nowtime->tm_hour ) == 0) && ( nowtime->tm_min ) == 0) ) : { : if( lock_flag == 0 ) : { : /* do something */ : lock_flag = 1; : } : }else{ : lock_flag = 0; : } : } 整體而言,我認為這段是邏輯上的錯誤,可再看一下整體,再想一下下面說明: 你只要在 00:00 時,就會一直不斷做 log 寫入的動作,當然若那個 /* do something */ 若是一大狗票麻煩的事情,若一執行就花 10 分鐘以上, process 的確會莫名被 hang 住,應該就進入所謂的 zombie 狀態。 我認為下面這種邏輯應該才是你要的 FILE *fp; int counter=0, has_write_flag=0; time_t cur_time_long; struct tm* cur_time; remove(LOGNAME); while(1){ /* 取得現在時間 */ time(&cur_time_long); cur_time=localtime(&cur_time_long); Sleep(200); /* sleep for some time*/ /* 如果還沒寫過,且時間對的話 */ if(has_write_flag==0 && cur_time->tm_min==WRITE_MIN && \ cur_time->tm_hour==WRITE_HOUR){ /* do something */ fp=fopen(LOGNAME, "a"); fprintf(fp, "line %d\n", ++counter); fclose(fp); /* don't setting flag */ has_write_flag=1; /* output show */ printf("has write line: %d\n", counter); } /* 如果已經寫過,且時間對的話,跳過不做 */ else if (has_write_flag==1 && (cur_time->tm_min==WRITE_MIN && \ cur_time->tm_hour==WRITE_HOUR) ){ continue; } /* 時間不對,不管有沒有寫過,flag 清 0 */ else { has_write_flag=0; } } ---- 上面的 if-else 那裡可以化得再簡一點,這裡保持 KISS 原則。 不保證你的問題一定是在這裡,但可以保證的是,你原本想要的,應該是這樣才對。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41

09/13 19:42, , 1F
Sleep的時間是ms,所以要乘1000,然後else if其實不用
09/13 19:42, 1F

09/13 19:44, , 2F
zombie是不斷執行吃資源的process.且用kill無法停止
09/13 19:44, 2F

09/13 19:44, , 3F
因此之後的linux版本提供killall去終止這程式
09/13 19:44, 3F

09/13 19:45, , 4F
說穿了就是原原po在執行此程式時.把它改成背景執行
09/13 19:45, 4F

09/13 19:46, , 5F
而它又一直不斷的跑,資源越來越少.實際上我覺得此程式
09/13 19:46, 5F

09/13 19:47, , 6F
應該要把sec也考慮進去.他應該是想寫daemon程式
09/13 19:47, 6F

09/13 19:48, , 7F
但是他很多條件沒加進去.
09/13 19:48, 7F

09/13 19:46, , 8F
else if 真正的作用,是在00:00時只執行一次,不然他的動
09/13 19:46, 8F

09/13 19:47, , 9F
作(原原po的動作),是在00:00時重覆執行。另 Linux 之
09/13 19:47, 9F

09/13 19:47, , 10F
Sleep 若為 ms, 那就真的不適合用 1 吧
09/13 19:47, 10F

09/13 19:48, , 11F
Linux 根本就沒有 Sleep() 吧, 只有 sleep(秒) 跟
09/13 19:48, 11F

09/13 19:48, , 12F
nanosleep, 有些會有 msleep
09/13 19:48, 12F
補齊, 謝謝 uranusjr 解釋 Sleep ※ 編輯: tropical72 來自: 180.177.78.41 (09/13 19:50)

09/13 19:49, , 13F
usleep<--這比較是我常用的.
09/13 19:49, 13F

09/13 19:51, , 14F
#include <unistd.h>
09/13 19:51, 14F

09/13 19:51, , 15F
unsigned int sleep(unsigned int seconds);<--有的
09/13 19:51, 15F

09/13 19:52, , 16F
我猜他打錯字
09/13 19:52, 16F

09/13 20:17, , 17F
zombie是指你的程式己經自己結束了,可是parrent process
09/13 20:17, 17F

09/13 20:17, , 18F
沒有call wait()
09/13 20:17, 18F

09/13 21:00, , 19F
謝謝樓上的指正
09/13 21:00, 19F

09/13 22:30, , 20F
樓樓上正姐 XD
09/13 22:30, 20F

09/15 13:41, , 21F
謝謝大家的幫忙
09/15 13:41, 21F
文章代碼(AID): #1ERp-JFk (C_and_CPP)
文章代碼(AID): #1ERp-JFk (C_and_CPP)