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

看板C_and_CPP (C/C++)作者 (みなさん、こんにちは)時間8年前 (2017/12/31 14:38), 8年前編輯推噓8(9127)
留言37則, 10人參與, 9年前最新討論串2/3 (看更多)
為什麼用 SIGINT 可能比 SIGALRM 好的幾個原因 1. Flexibility SIGINT 不需要將時間間隔寫進程式 可以透過系統的殼層腳本觸發 隨情況調整觸發的頻率跟是否要觸發 這有助於程式的彈性和降低重新編譯的次數 甚至可能之後 想要對寫好的程式進行 profile 去計算 cache miss rate 等等 就可以免去 SIGALRM 開銷帶來的副作用 因此 SIGINT 可以說是方便很多 在很多時候會有意想不到的好處 2. Stability A. Timer Inheritance 計時器繼承 fork() / exec()-s: POSIX 標準規定使用 alarm() 觸發計時器時 在往後調用 fork() 的時候會清除 在往後調用 exec() 系列函數的時候 保留剩餘的時間到下一個行程映像持續計算 Alarms created by alarm are preserved across execve and are not inherited by children created via fork. 然而標準對 signal disposition 卻有不同的邏輯 在 fork() 的時候被繼承 在 exec() 的時候卻會被重設成預設的 handler A child created via fork inherits a copy of its parent's signal dispositions. During an execve, the dispositions of handled signals are reset to the default; the dispositions of ignored signals are left unchanged. 不一致的設計潛在隱患 可能導致非常難以除錯或是異常的行為 B. Timer Anomaly 計時器異常 除此之外 Linux 對 setitimer() 的異常行為有以下的描述: The generation and delivery of a signal are distinct, and only one instance of each of the signals listed above may be pending for a process. Under very heavy loading, an ITIMER_REAL timer may expire before the signal from a previous expiration has been delivered. The second signal in such an event will be lost. ITIMER_REAL 觸發的是 SIGALRM 如果要避免上述的問題 可以採用 ITIMER_VIRTUAL 計時器 而它相對應的信號是 SIGVTALRM 但是它的時間不再是 wall time (real time) 而是 execution time C. Unspecified Interactions 未定義行為 sleep(), usleep(), ualarm(), setitimer(): 根據 POSIX 的標準 所有的計時器都是 per-process basis 而且不會 stack 起來 所以設定新的計時器會覆蓋舊有的計時器 因此每次檢查 alarm 的返回值至關重要 不然可能導致不再有 SIGALRM 被觸發 3. Conclusions 計時器的設定有很多瑣碎的細節 甚至可能有上述我沒想到的更隱晦的 都可能在一個不經意的情況 讓程式運作的不如預期 除非真的很需要計時器這種對時間很要求的情況 才有使用的必要 如果只是想要看看目前執行的進度 定期寫記錄到硬碟或 SIGINT 不失為一個好方法 ※ 引述《BreathWay (息尉)》之銘言: : 標題: [問題] 如何設定時間上限使程式自動輸出? : 時間: Sat Dec 30 11:04:55 2017 : : 問題(Question): : 我寫了一個以暴力演算法求最佳解的程式, : 主要是透過不斷更新所找到的更好的解來達成。 : 但是我希望能設定一個時間上限, : 如果程式還沒跑完就直接輸出目前找到的最好的解。 : 請問有辦法在 C 裡面實作這個功能嗎? : : 推 Hazukashiine: POSIX Thread 或是 Signal Handler 12/30 14:32 : → Hazukashiine: 像是可以 SIGINT 時印出 ex. ping 12/30 14:34 : → 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 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.116.185.23 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1514702318.A.C18.html

12/31 16:36, 8年前 , 1F
你到底咳了什麼
12/31 16:36, 1F

12/31 16:39, 8年前 , 2F
原Po: 請教我打造一艘船 H大: 你需要這台潛水艇 其他人: 要
12/31 16:39, 2F

12/31 16:39, 8年前 , 3F
不要先試試這條小船 設計簡單又可以馬上下水
12/31 16:39, 3F

12/31 16:39, 8年前 , 4F
原po: 其實我我需要小船 是貨輪那種等級的
12/31 16:39, 4F

12/31 16:41, 8年前 , 5F
H大: 可是潛水艇除了在水上走 還能潛水 你看潛水多棒 在水
12/31 16:41, 5F

12/31 16:41, 8年前 , 6F
上走可能會被太陽曬到 會被月亮照到 會被海鳥噴屎 會撞到冰
12/31 16:41, 6F

12/31 16:41, 8年前 , 7F
12/31 16:41, 7F
可是有一艘潛艇便宜好打造又安全 就直接打造一艘潛艇 >///< 1. signal(SIGINT, handler); 2. static void handler(int sig) { /* progress */ } 3. add "one line" with crontab for running periodically ※ 編輯: Hazukashiine (122.116.185.23), 12/31/2017 17:12:35

12/31 17:04, 8年前 , 8F
樓上比喻怪怪的吧… 幫翻譯
12/31 17:04, 8F

12/31 17:04, 8年前 , 9F
OP:我需要一個能跨過海洋的東西
12/31 17:04, 9F

12/31 17:04, 8年前 , 10F
H:潛水艇很好用,好處是oooxxx
12/31 17:04, 10F

12/31 17:04, 8年前 , 11F
G:你到底嗑了什麼用船就好幹嘛要潛水艇
12/31 17:04, 11F

12/31 17:15, 8年前 , 12F
都行都行 能過海不要翻船進水就好了嘛 QAQ
12/31 17:15, 12F

12/31 18:53, 8年前 , 13F
問題是潛水艇的code就很簡單,貨輪比較難
12/31 18:53, 13F

12/31 18:53, 8年前 , 14F
類比根本錯誤
12/31 18:53, 14F

12/31 23:03, 8年前 , 15F
對 SIGALRM 的幾個現存問題講得很精闢,推
12/31 23:03, 15F

01/01 01:59, 9年前 , 16F
潛艇沒有很難用啊 比喻不好喔
01/01 01:59, 16F

01/01 08:53, 9年前 , 17F
signal好用到炸好不
01/01 08:53, 17F

01/01 09:25, 9年前 , 18F
我一直強調你有達到原Po的目的 要求是「指定時間好嗎」 你
01/01 09:25, 18F

01/01 09:25, 9年前 , 19F
去crontab塞的時間算得進去嗎?
01/01 09:25, 19F

01/01 09:29, 9年前 , 20F
要在C裡面實作這個功能 你還要人家寫script 講一堆有的沒有
01/01 09:29, 20F

01/01 09:29, 9年前 , 21F
的 回答問題真的這麼難嗎 扯東扯西 你前面兩點跟用SIGALRM
01/01 09:29, 21F

01/01 09:29, 9年前 , 22F
要寫的不是一樣嗎
01/01 09:29, 22F

01/01 09:30, 9年前 , 23F
「如何做到指定時間停止」「你可以偶爾Ctrl+C偷看一下時間
01/01 09:30, 23F

01/01 09:30, 9年前 , 24F
啊」這樣真的是有在回答問題嗎
01/01 09:30, 24F

01/01 09:34, 9年前 , 25F
而且你說得哪一個問題 不是使用C語言或是系統提供的Library
01/01 09:34, 25F

01/01 09:34, 9年前 , 26F
可能會面對的問題?為何還要在那恐嚇Programmer? 你要Flexi
01/01 09:34, 26F

01/01 09:34, 9年前 , 27F
bility和Stability,有其他更適合的做法?重點是達到原Po的
01/01 09:34, 27F

01/01 09:34, 9年前 , 28F
目的
01/01 09:34, 28F

01/01 09:36, 9年前 , 29F
「Linux, C, 指定時間停止」
01/01 09:36, 29F

01/02 18:21, 9年前 , 30F
哎呦 7pupu 嘻嘻 扯東扯西的不知道是誰喔
01/02 18:21, 30F

01/02 19:16, 9年前 , 31F
@galic 給你一個連結 http://tinyurl.com/q7gem8l
01/02 19:16, 31F

01/03 01:02, 9年前 , 32F
我是覺得原 po真正的目的的確是偷看進度啦
01/03 01:02, 32F

01/03 06:27, 9年前 , 33F
偷看進度的話其實用另外一個thread定時把結果寫進某檔
01/03 06:27, 33F

01/03 06:28, 9年前 , 34F
案(或者直接寫入目前最佳解)好像比較好? XD
01/03 06:28, 34F

01/03 06:29, 9年前 , 35F
除非結果還需要做很壟長的aggeration
01/03 06:29, 35F

01/03 12:16, 9年前 , 36F
所以我推可以log 進度最快 XD
01/03 12:16, 36F

01/03 12:49, 9年前 , 37F
這些爭辯, 讓我想到黑貓白貓論 XD
01/03 12:49, 37F
文章代碼(AID): #1QI8NkmO (C_and_CPP)
文章代碼(AID): #1QI8NkmO (C_and_CPP)