看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: Win10, Linux, ...) Linux 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) GCC 問題(Question): 我寫了一個以暴力演算法求最佳解的程式, 主要是透過不斷更新所找到的更好的解來達成。 但是我希望能設定一個時間上限, 如果程式還沒跑完就直接輸出目前找到的最好的解。 請問有辦法在 C 裡面實作這個功能嗎? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.249.201 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1514603097.A.868.html
loveflames: SIGALRM 12/30 11:19
Hazukashiine: POSIX Thread 或是 Signal Handler 12/30 14:32
Hazukashiine: 像是可以 SIGINT 時印出 ex. ping 12/30 14:34
edisonhello: clock <ctime> 可以用 12/30 15:38
alan23273850: 透過signal是還不錯的方法,不過如果不想碰系統底層 12/30 16:04
alan23273850: 的話其實我有另一個創意方法,你可以設一個全域變數 12/30 16:04
alan23273850: 紀錄程式一開始的時間戳,之後在code會重複執行的地 12/30 16:05
alan23273850: 方插入查詢當下時間戳的code,跟最一開始的全域變數 12/30 16:06
alan23273850: 相減,超過一定的值就代表跑太久,跳出迴圈即可 12/30 16:06
alan23273850: 這樣副作用是會降低程式效率,112我覺得可以弄signa 12/30 16:07
b0920075: 用signal算滿簡單的吧XDDD跟112有什麼關係 12/30 18:26
longlongint: 直接看迴圈計數值最簡單 12/30 18:45
Lipraxde: 設個條件求到夠好的解就跳出也不錯啊 12/30 19:42
感謝各位的回覆 研究了一下signal似乎是要^C才能發揮作用 但我希望的是程式自動在指定的時間一到後就印出最佳解 迴圈計數值是一個簡單可行的方法 不過我的程式在每次迴圈的過程中所經過的時間會不太一樣 而最佳解的值比較難預估 無法使用設條件的方法 紀錄時間戳的方法可能比較接近限制時間上限的原旨 不過的確也會造成每次檢查降低程式效率 ※ 編輯: BreathWay (140.112.249.201), 12/30/2017 22:21:21
Hazukashiine: 事實上你可以搭配 Linux 的 cron (job scheduler) 12/30 22:35
Hazukashiine: 來達成定時發送 SIGINT 的任務 不一定要人親自去按 12/30 22:35
galic: Ctrl+C只是其中一種Signal(SIGINT)好嗎 然後推文為何一直叫 12/30 23:01
galic: 人家用SIGINT 明明就有timer用的signal 12/30 23:01
galic: 你也只有polling counter或是透過timer兩種作法 12/30 23:03
galic: 但照po後來的回覆 這種需求就是要走timer阿 12/30 23:06
galic: 那就看一看timer的文件 https://tinyurl.com/lo9e3w3 12/30 23:08
galic: https://tinyurl.com/d5fw2rh 12/30 23:09
Hazukashiine: 用 SIGINT 是因為方便 彈性比較高 可以搭配腳本使用 12/30 23:40
Hazukashiine: 如果程式正在前景跑 但是手癢想在 timer expired 12/30 23:40
Hazukashiine: 前看偷看 按一下 ctrl + c 就可以了 如果想要靜靜放 12/30 23:40
Hazukashiine: 後景跑 就指令後面加 & 如果直接用樓上的方法寫死在 12/30 23:40
Hazukashiine: 程式裡編譯好的話 就沒有這種好處了 更何況樓主可能 12/30 23:40
Hazukashiine: 只是想偶爾偷看一下進度而已 我覺得用 SIGINT 合適 12/30 23:40
galic: 不用幫別人腦補 12/30 23:49
Schottky: 要鬧鐘給一支市話的概念,也是能用但好像哪裡不太對 12/31 05:22
Killercat: 用chrono拿start time, 在loop裡面每做完一次運算就 12/31 08:17
Killercat: 再拿一次timer, 去相減看看到threshold沒 12/31 08:17
Killercat: 如果你對時間的精度要求不是特別高的話,這最簡單 12/31 08:18
Killercat: 外部用OS SDK/Signal去砍比較準 但是要依賴外部 12/31 08:19
Killercat: 這前提是假設你的演算是不可中斷的 12/31 08:20
Killercat: 但是你說brute force, 單次演算應該都不會太長才是 12/31 08:20
alan23273850: 順帶提醒一下,最好測一下持續查詢時間戳這個動作對 12/31 08:47
alan23273850: 效能的影響,這個有時候會超乎你想像,牽涉到system 12/31 08:47
alan23273850: call的函式都要注意,通常時間比例是關鍵 12/31 08:48
GaliTW: Linux有vDSO 不用擔心 12/31 09:04
steve1012: 感覺原 po只是要一個簡單的方法可以停止而已xD 應該不 12/31 10:21
steve1012: 用太精細? 12/31 10:21
steve1012: 你也可以output 每 k個 iteration 後的解就好 12/31 10:22
steve1012: 這樣你想停就直接ctrl c 12/31 10:22
Killercat: alan倒是說到重點,要是每次運算都只有10幾個clock 12/31 10:43
Killercat: 那真的會造成很巨大的影響(這是絕對有可能的) 12/31 10:43
steve1012: 可以每 k次 check 就好 12/31 10:43
Killercat: 不過普通情況下 profiling一下 應該沒問題就取簡單的吧 12/31 10:44
jasonwu23: 他要時間到印解答呀 你ctrl c程式跳出來了還能印嗎 12/31 17:23
Hazukashiine: 可以 ctrl+c (SIGINT) 印出 ctrl+\ (SIGQUIT) 結束 12/31 17:26
Hazukashiine: 這些 signals 都是可以重載的 >< 12/31 17:27
Killercat: 不過牽扯到kernel space的呼叫的話 記得sigint handler 12/31 23:11
Killercat: 要做收尾動作,不然kernel state可能會出包 12/31 23:11
Killercat: 比方說用ioctl設旗標等等動作都要小心點 12/31 23:12
y3k: 用過SIGINT+1 XD 01/01 11:23
alan23273850: 上面steve大大也有提到一點,如果每次iter時間差不 01/01 14:39
alan23273850: 多的話,也可以用迭代次數取代時間,以省去系統呼叫 01/01 14:39
sunneo: 照其他語言的習慣是設cancellation token,並讓你的演算法 01/01 17:58
sunneo: 改寫成iterator,每個iteration都看時間。 01/01 18:00
x000032001: 想要不影響效能嗎 寫個thread處理吧 (X 01/01 20:41
joe820730: 是我的話會考慮寫個thread計時...什麼signal都不用處理 01/01 21:46
bben900911: 笨笨如我也會這樣。 把最新結果放在全域或heap,另一 01/02 11:04
bben900911: 個thread固定wait自己,起來後就去取值@@ 01/02 11:04
Lipraxde: 這樣的話要注意互斥的問題呢 01/02 13:09
jimfan: 贊同用signal最精簡 01/03 09:59