標籤:shell linux 後台進程
近日遇到shell後台啟動進程,輸入ctrl+z被掛起的問題
具體描述如下:
1、現有兩個shell指令碼,grandfather.sh和father.sh,兩個C++程式son1和son2,其中son1為普通程式,son2使用occi串連oracle資料庫
調用關係為
2、Father.sh啟動son1和son2後,退出到Grandfather.sh,此時在Grandfather.sh中安ctrl+z後,使用ps aux查看son1和son2的進程狀態分別為T和S
3、個人認為,既然Father.sh在後台啟動son1和son2,那麼son1和son2就不應該再受前台shell的影響,不再接收前台shell的訊號,更何況Father.sh已經退出了,son1和son2的父進程PID已經為1了。但其實,Grandfather.sh與son1和son2還存在繼承關係,共用一些資源和訊號,導致son1和son2會收到ctrl+z訊號,從而son1被掛起,此時kill掉Grandfather.sh後,son1正常,說明son1與Grandfather.sh確實還有關聯。
4、對於son2,為何沒被掛起呢?原因是occi會捕獲ctrl+z等訊號,所以表面上son2沒有收到影響,但實際上可能connection已經復原或出錯了。
5、解決方案分為兩種,一是在c++程式中屏蔽訊號,二是在shell指令碼中屏蔽訊號
6、在c++程式中屏蔽ctrl+z等訊號
//signum為訊號的數字表示,其中SIGSTOP=ctrl+c,SIGTSTP=ctrl+z int32_t signum; //callback為訊號響應時的回呼函數 SignalCallback callback; struct sigaction act, oldact; memset(&act, 0, sizeof(act)); memset(&oldact, 0, sizeof(oldact)); sigemptyset(&act.sa_mask); act.sa_handler = callback; return sigaction(signum, &act, &oldact);
但occi會優先於c++程式捕獲訊號,所以此方法對son2程式不起作用
7、在shell指令碼中屏蔽ctrl+z等訊號
trap exit SIGUSR2trap exit SIGUSR1trap exit SIGTERMtrap exit SIGSTOPtrap exit SIGTTINtrap exit SIGTSTPtrap exit SIGTTINtrap exit SIGTTOUtrap exit SIGCHLDtrap exit SIGINT
trap命令需要兩個參數,第二個參數為訊號的編號,第一個參數為收到訊號時,要替換成的動作,若只是屏蔽訊號,則可將第一個參數設為‘’
關於後台啟動並執行原理,請參考文章 http://www.cnblogs.com/SuperXJ/archive/2011/10/31/2230314.html
關於linux後台運行進程如何屏蔽ctrl+z