Rumah > Soal Jawab > teks badan
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一发出,相当于所有进程包括子进程都会被强行杀掉,这种情况下程序内部根本无法进行什么逻辑判断和处理,整个程序就属于异常退出状态?