我有一個程序使用fork()
來創建子進程。我已經看到了各種使用wait()
來等待子進程在關閉之前結束的例子,但是我想知道我能做些什麼來簡單地檢查文件進程是否仍在運行。在C++中檢查子進程的狀態
我基本上有一個無限循環,我想要做的事,如:
if(child process has ended) break;
我怎麼會去這樣做呢?
我有一個程序使用fork()
來創建子進程。我已經看到了各種使用wait()
來等待子進程在關閉之前結束的例子,但是我想知道我能做些什麼來簡單地檢查文件進程是否仍在運行。在C++中檢查子進程的狀態
我基本上有一個無限循環,我想要做的事,如:
if(child process has ended) break;
我怎麼會去這樣做呢?
使用waitpid()
與WNOHANG
選項。
int status;
pid_t result = waitpid(ChildPID, &status, WNOHANG);
if (result == 0) {
// Child still alive
} else if (result == -1) {
// Error
} else {
// Child exited
}
您不需要等待孩子,直到您得到SIGCHLD
信號。如果您收到該信號,您可以致電wait
並查看它是否是您要查找的子過程。如果你沒有收到信號,那孩子還在跑步。
很顯然,如果您不需要做任何事情,孩子就可以完成,只需撥打wait
即可。
我怎麼知道我是否得到了這個信號? – Alex 2011-03-11 21:43:28
編輯:如果你只是想知道子進程是否停止運行,那麼其他答案可能會更好。當一個進程可以進行多次計算而不一定終止時,我的工作就更多地與同步有關。
如果您有一些代表子計算的對象,請添加一個方法,如bool isFinished()
,如果孩子已完成,則返回true。在表示操作是否完成的對象中有一個私有bool成員。最後,在子進程完成其計算所調用的同一對象上有另一個私有的方法setFinished(bool)
。
現在最重要的是互斥鎖。確保每次嘗試訪問任何成員時都鎖定每個對象的互斥鎖,包括在bool isFinished()
和setFinished(bool)
方法中。
EDIT2:(一些OO澄清)
自從我被要求解釋這到底是怎麼用OO做,我給一些建議,雖然它很大程度上取決於整體的問題,所以帶上一堆鹽吧。使用C風格編寫的大部分程序都有一個浮動的對象是不一致的。
ChildComputation* myChild = new ChildComputation(/*params*/);
ChildPID= fork();
if (ChildPID == 0) {
// will do the computation and automatically set its finish flag.
myChild->doComputation();
}
else {
while (1) { // your infinite loop in the parent
// ...
// check if child completed its computation
if (myChild->isFinished()) {
break;
}
}
// at the end, make sure the child is no runnning, and dispose of the object
// when you don't need it.
wait(ChildPID);
delete myChild;
}
希望是有道理的:
舉個簡單的例子,你可以有一個類在你的主程序,在那裏你叉叫ChildComputation
class ChildComputation {
public:
//constructor
ChildComputation(/*some params to differentiate each child's computation*/) :
// populate internal members here {
}
~ChildComputation();
public:
bool isFinished() {
m_isFinished; // no need to lock mutex here, since we are not modifying data
}
void doComputation() {
// put code here for your child to execute
this->setFinished(true);
}
private:
void setFinished(bool finished) {
m_mutex.lock();
m_isFinished = finished;
m_mutex.unlock();
}
private:
// class members
mutex m_mutexLock; // replace mutex with whatever mutex you are working with
bool m_isFinished;
// other stuff needed for computation
}
現在。
要重申,上面我所編寫的是C的醜陋的合併和C++(在語法方面不大,但風格/設計),並且就在那裏給你OO同步一瞥,在你的上下文中。
我不確定如何使我的子進程成爲一個對象。這是我第一次做這種編程,所以我的理解還是比較基礎的。現在我只有一個主函數,它創建兩個管道然後分叉,並且具有使用pid分隔父進程和子進程的代碼的if-else語句。我怎麼能讓這個面向對象? – Alex 2011-03-11 21:41:25
如果你的問題很簡單,也許你甚至不需要做它OO,我只是假設它,因爲你把C++作爲標籤。這實際上取決於你想要解決的整體問題。 Erik的答案是最適合您當前的代碼。我會添加一些東西到我的答案澄清雖然。 – 2011-03-11 21:49:25
這是有道理的。我認爲它確實比C++問題更像C問題。我習慣於使用C++,並且在程序中包含一些C++函數,但程序的這部分確實更像C語言。我想在將來我會將它標記爲C/C++。 – Alex 2011-03-11 22:21:46
因此,ChildPID是我用來區分父母和孩子的結果,並且結果是一個新的pid_t,它使得一個新的子流程監視孩子退出? – Alex 2011-03-11 21:46:44
不,ChildPID是'fork()'返回的子進程ID。 'waitpid()'只是一個返回一個值的函數:'0','ChildPid'或'-1' – Erik 2011-03-11 21:49:08
嗯,我的意思是我做了一個'pid_t'來說'pid = fork()'。現在爲我的父母和孩子編寫代碼我有一個if-else檢查'if(pid)'來標識父進程,因爲在父進程中'pid'包含孩子的pid編號,並且在孩子'pid'中包含'0'。所以,如果我正確理解這一點,我相信我應該在你說過使用'ChildPID'的地方使用'pid'。 – Alex 2011-03-11 21:56:18