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

作者: Hazukashiine (私は幸せです)   2017-12-31 14:38:34
為什麼用 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
作者: steve1012 (steve)   2016-01-01 01:59:00
潛艇沒有很難用啊 比喻不好喔
作者: galic (嘎利)   2017-12-31 16:36:00
你到底咳了什麼原Po: 請教我打造一艘船 H大: 你需要這台潛水艇 其他人: 要不要先試試這條小船 設計簡單又可以馬上下水原po: 其實我我需要小船 是貨輪那種等級的H大: 可是潛水艇除了在水上走 還能潛水 你看潛水多棒 在水上走可能會被太陽曬到 會被月亮照到 會被海鳥噴屎 會撞到冰山
作者: CoNsTaR ((const *))   2017-12-31 17:04:00
樓上比喻怪怪的吧… 幫翻譯OP:我需要一個能跨過海洋的東西H:潛水艇很好用,好處是oooxxxG:你到底嗑了什麼用船就好幹嘛要潛水艇
作者: Hazukashiine (私は幸せです)   2017-12-31 17:15:00
都行都行 能過海不要翻船進水就好了嘛 QAQ
作者: Darkautism (達卡特森)   2017-12-31 18:53:00
問題是潛水艇的code就很簡單,貨輪比較難類比根本錯誤
作者: Schottky (順風相送)   2017-12-31 23:03:00
對 SIGALRM 的幾個現存問題講得很精闢,推
作者: TWkobe (中華柯比)   2016-01-01 08:53:00
signal好用到炸好不
作者: galic (嘎利)   2016-01-01 09:25:00
我一直強調你有達到原Po的目的 要求是「指定時間好嗎」 你去crontab塞的時間算得進去嗎?要在C裡面實作這個功能 你還要人家寫script 講一堆有的沒有的 回答問題真的這麼難嗎 扯東扯西 你前面兩點跟用SIGALRM要寫的不是一樣嗎「如何做到指定時間停止」「你可以偶爾Ctrl+C偷看一下時間啊」這樣真的是有在回答問題嗎而且你說得哪一個問題 不是使用C語言或是系統提供的Library可能會面對的問題?為何還要在那恐嚇Programmer? 你要Flexibility和Stability,有其他更適合的做法?重點是達到原Po的目的「Linux, C, 指定時間停止」
作者: CoNsTaR ((const *))   2016-01-02 18:21:00
哎呦 7pupu 嘻嘻 扯東扯西的不知道是誰喔
作者: LPH66 (-6.2598534e+18f)   2016-01-02 19:16:00
@galic 給你一個連結 http://tinyurl.com/q7gem8l
作者: steve1012 (steve)   2016-01-03 01:02:00
我是覺得原 po真正的目的的確是偷看進度啦
作者: Killercat (殺人貓™)   2016-01-03 06:27:00
偷看進度的話其實用另外一個thread定時把結果寫進某檔案(或者直接寫入目前最佳解)好像比較好? XD除非結果還需要做很壟長的aggeration
作者: steve1012 (steve)   2016-01-03 12:16:00
所以我推可以log 進度最快 XD
作者: yvb   2016-01-03 12:49:00
這些爭辯, 讓我想到黑貓白貓論 XD

Links booklink

Contact Us: admin [ a t ] ucptt.com