[問題] 如何設定時間上限使程式自動輸出?

看板C_and_CPP作者 (息尉)時間8年前 (2017/12/30 11:04), 8年前編輯推噓9(9055)
留言64則, 19人參與, 9年前最新討論串1/3 (看更多)
開發平台(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

12/30 11:19, 8年前 , 1F
SIGALRM
12/30 11:19, 1F

12/30 14:32, 8年前 , 2F
POSIX Thread 或是 Signal Handler
12/30 14:32, 2F

12/30 14:34, 8年前 , 3F
像是可以 SIGINT 時印出 ex. ping
12/30 14:34, 3F

12/30 15:38, 8年前 , 4F
clock <ctime> 可以用
12/30 15:38, 4F

12/30 16:04, 8年前 , 5F
透過signal是還不錯的方法,不過如果不想碰系統底層
12/30 16:04, 5F

12/30 16:04, 8年前 , 6F
的話其實我有另一個創意方法,你可以設一個全域變數
12/30 16:04, 6F

12/30 16:05, 8年前 , 7F
紀錄程式一開始的時間戳,之後在code會重複執行的地
12/30 16:05, 7F

12/30 16:06, 8年前 , 8F
方插入查詢當下時間戳的code,跟最一開始的全域變數
12/30 16:06, 8F

12/30 16:06, 8年前 , 9F
相減,超過一定的值就代表跑太久,跳出迴圈即可
12/30 16:06, 9F

12/30 16:07, 8年前 , 10F
這樣副作用是會降低程式效率,112我覺得可以弄signa
12/30 16:07, 10F

12/30 18:26, 8年前 , 11F
用signal算滿簡單的吧XDDD跟112有什麼關係
12/30 18:26, 11F

12/30 18:45, 8年前 , 12F
直接看迴圈計數值最簡單
12/30 18:45, 12F

12/30 19:42, 8年前 , 13F
設個條件求到夠好的解就跳出也不錯啊
12/30 19:42, 13F
感謝各位的回覆 研究了一下signal似乎是要^C才能發揮作用 但我希望的是程式自動在指定的時間一到後就印出最佳解 迴圈計數值是一個簡單可行的方法 不過我的程式在每次迴圈的過程中所經過的時間會不太一樣 而最佳解的值比較難預估 無法使用設條件的方法 紀錄時間戳的方法可能比較接近限制時間上限的原旨 不過的確也會造成每次檢查降低程式效率 ※ 編輯: BreathWay (140.112.249.201), 12/30/2017 22:21:21

12/30 22:35, 8年前 , 14F
事實上你可以搭配 Linux 的 cron (job scheduler)
12/30 22:35, 14F

12/30 22:35, 8年前 , 15F
來達成定時發送 SIGINT 的任務 不一定要人親自去按
12/30 22:35, 15F

12/30 23:01, 8年前 , 16F
Ctrl+C只是其中一種Signal(SIGINT)好嗎 然後推文為何一直叫
12/30 23:01, 16F

12/30 23:01, 8年前 , 17F
人家用SIGINT 明明就有timer用的signal
12/30 23:01, 17F

12/30 23:03, 8年前 , 18F
你也只有polling counter或是透過timer兩種作法
12/30 23:03, 18F

12/30 23:06, 8年前 , 19F
但照po後來的回覆 這種需求就是要走timer阿
12/30 23:06, 19F

12/30 23:08, 8年前 , 20F
那就看一看timer的文件 https://tinyurl.com/lo9e3w3
12/30 23:08, 20F

12/30 23:09, 8年前 , 21F

12/30 23:40, 8年前 , 22F
用 SIGINT 是因為方便 彈性比較高 可以搭配腳本使用
12/30 23:40, 22F

12/30 23:40, 8年前 , 23F
如果程式正在前景跑 但是手癢想在 timer expired
12/30 23:40, 23F

12/30 23:40, 8年前 , 24F
前看偷看 按一下 ctrl + c 就可以了 如果想要靜靜放
12/30 23:40, 24F

12/30 23:40, 8年前 , 25F
後景跑 就指令後面加 & 如果直接用樓上的方法寫死在
12/30 23:40, 25F

12/30 23:40, 8年前 , 26F
程式裡編譯好的話 就沒有這種好處了 更何況樓主可能
12/30 23:40, 26F

12/30 23:40, 8年前 , 27F
只是想偶爾偷看一下進度而已 我覺得用 SIGINT 合適
12/30 23:40, 27F

12/30 23:49, 8年前 , 28F
不用幫別人腦補
12/30 23:49, 28F

12/31 05:22, 8年前 , 29F
要鬧鐘給一支市話的概念,也是能用但好像哪裡不太對
12/31 05:22, 29F

12/31 08:17, 8年前 , 30F
用chrono拿start time, 在loop裡面每做完一次運算就
12/31 08:17, 30F

12/31 08:17, 8年前 , 31F
再拿一次timer, 去相減看看到threshold沒
12/31 08:17, 31F

12/31 08:18, 8年前 , 32F
如果你對時間的精度要求不是特別高的話,這最簡單
12/31 08:18, 32F

12/31 08:19, 8年前 , 33F
外部用OS SDK/Signal去砍比較準 但是要依賴外部
12/31 08:19, 33F

12/31 08:20, 8年前 , 34F
這前提是假設你的演算是不可中斷的
12/31 08:20, 34F

12/31 08:20, 8年前 , 35F
但是你說brute force, 單次演算應該都不會太長才是
12/31 08:20, 35F

12/31 08:47, 8年前 , 36F
順帶提醒一下,最好測一下持續查詢時間戳這個動作對
12/31 08:47, 36F

12/31 08:47, 8年前 , 37F
效能的影響,這個有時候會超乎你想像,牽涉到system
12/31 08:47, 37F

12/31 08:48, 8年前 , 38F
call的函式都要注意,通常時間比例是關鍵
12/31 08:48, 38F

12/31 09:04, 8年前 , 39F
Linux有vDSO 不用擔心
12/31 09:04, 39F

12/31 10:21, 8年前 , 40F
感覺原 po只是要一個簡單的方法可以停止而已xD 應該不
12/31 10:21, 40F

12/31 10:21, 8年前 , 41F
用太精細?
12/31 10:21, 41F

12/31 10:22, 8年前 , 42F
你也可以output 每 k個 iteration 後的解就好
12/31 10:22, 42F

12/31 10:22, 8年前 , 43F
這樣你想停就直接ctrl c
12/31 10:22, 43F

12/31 10:43, 8年前 , 44F
alan倒是說到重點,要是每次運算都只有10幾個clock
12/31 10:43, 44F

12/31 10:43, 8年前 , 45F
那真的會造成很巨大的影響(這是絕對有可能的)
12/31 10:43, 45F

12/31 10:43, 8年前 , 46F
可以每 k次 check 就好
12/31 10:43, 46F

12/31 10:44, 8年前 , 47F
不過普通情況下 profiling一下 應該沒問題就取簡單的吧
12/31 10:44, 47F

12/31 17:23, 8年前 , 48F
他要時間到印解答呀 你ctrl c程式跳出來了還能印嗎
12/31 17:23, 48F

12/31 17:26, 8年前 , 49F
可以 ctrl+c (SIGINT) 印出 ctrl+\ (SIGQUIT) 結束
12/31 17:26, 49F

12/31 17:27, 8年前 , 50F
這些 signals 都是可以重載的 ><
12/31 17:27, 50F

12/31 23:11, 8年前 , 51F
不過牽扯到kernel space的呼叫的話 記得sigint handler
12/31 23:11, 51F

12/31 23:11, 8年前 , 52F
要做收尾動作,不然kernel state可能會出包
12/31 23:11, 52F

12/31 23:12, 8年前 , 53F
比方說用ioctl設旗標等等動作都要小心點
12/31 23:12, 53F

01/01 11:23, 9年前 , 54F
用過SIGINT+1 XD
01/01 11:23, 54F

01/01 14:39, 9年前 , 55F
上面steve大大也有提到一點,如果每次iter時間差不
01/01 14:39, 55F

01/01 14:39, 9年前 , 56F
多的話,也可以用迭代次數取代時間,以省去系統呼叫
01/01 14:39, 56F

01/01 17:58, 9年前 , 57F
照其他語言的習慣是設cancellation token,並讓你的演算法
01/01 17:58, 57F

01/01 18:00, 9年前 , 58F
改寫成iterator,每個iteration都看時間。
01/01 18:00, 58F

01/01 20:41, 9年前 , 59F
想要不影響效能嗎 寫個thread處理吧 (X
01/01 20:41, 59F

01/01 21:46, 9年前 , 60F
是我的話會考慮寫個thread計時...什麼signal都不用處理
01/01 21:46, 60F

01/02 11:04, 9年前 , 61F
笨笨如我也會這樣。 把最新結果放在全域或heap,另一
01/02 11:04, 61F

01/02 11:04, 9年前 , 62F
個thread固定wait自己,起來後就去取值@@
01/02 11:04, 62F

01/02 13:09, 9年前 , 63F
這樣的話要注意互斥的問題呢
01/02 13:09, 63F

01/03 09:59, 9年前 , 64F
贊同用signal最精簡
01/03 09:59, 64F
文章代碼(AID): #1QHm9PXe (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1QHm9PXe (C_and_CPP)