enum stats {OK,TLE,RE};
struct runstats{
stats stat;
int exitcode;
};
runstats system_tle(const char* tor,int tle){
runstats result;
auto Start=std::chrono::steady_clock::now();
pid_t p1=fork();
if (p1==0){
int ec=std::system(tor);
if (ec) result.stat=RE; else result.stat=OK;
result.exitcode=ec;
}else{
bool done=false;
while (std::chrono::steady_clock::now()<Start+std::chrono::milliseconds(tle*1000)&&!done)
if (kill(p1,0)!=0) done=true;
if (!done){
kill(p1,SIGKILL);
result.stat=TLE;
result.exitcode=-1;
}else exit(0);
}
return result;
}
我想用这段代码实现system函数的定时,也就是system在指定时间内不退出,用另外一个进程kill之。但以上这段代码为什么会出现问题?问题大概是这样的,无论子进程是否在规定时间内跑完,主线程都会执行一次kill并返回错误的结果。
巴扎黑2017-04-17 13:41:43
因你的目的描述不是很清楚,我只能猜測,你的意圖是: system(tor)調用可能會一直阻塞或長時間阻塞,如果它在規定時間內還沒執行完,就kill之?
在得到你確認之前,我先不回答這個問題。看了你的程式碼,先說兩個嚴重問題。
第一,父子程式有各自的資料記憶體空間。 linux使用了copy on write技術,fork後子進程會與父進程共享數據,但一旦子進程修改數據,就會copy一份出來。就如程式碼中的result,子進程一份,父進程一份,各不相干。你程式碼的寫法,把多進程當多執行緒來寫了!
第二,kill主程序pid即向主程序發送訊號,通常主程序在多進程裡是進程組組長,組長及組內所有的子程序都會收到訊號,包括system函數執行的程序也是屬於子進程,除非被system執行的進程自己改變了進程組id。這個SIGKILL一發出,相當於所有進程包含子進程都會被強行殺掉,這種情況下程式內部根本無法進行什麼邏輯判斷和處理,整個程式就屬於異常退出狀態?