上代码了
代码: 全选
#include <iostream>
#include <fstream>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
const double DELTA = 1.0;
const int TIME = 100;
const int MEM = 18192;
const int OFFSET = 10;
using namespace std;
char *pid_to_string(int pid)
{
char s[50];
sprintf(s,"%d",pid);
char *s1=s;
return s1;
}
int pid_to_string(int pid,char *s)
{
sprintf(s,"%d",pid);
return 0;
}
long get_memory(int pages)
{
long factor = 0;
factor = (long)sysconf(_SC_PAGESIZE);
return pages*factor/1024;
}
void get_timespec(struct timespec *s, int time)
{
s->tv_sec = time / 1000;
s->tv_nsec = (time % 1000 ) * 1000000;
}
/*
return 0 if OK
return 1 if MLE
*/
int check_memory(char *pid_string)
{
using std::ios_base;
using std::ifstream;
using std::string;
double vm_usage = 0.0;
double resident_set = 0.0;
// 'file' stat seems to give the most reliable results
//
char buffer[100];
sprintf(buffer,"/proc/%s/statm",pid_string);
ifstream statm_stream(buffer,ios_base::in);
long vmsize=0;
statm_stream>>vmsize;
vmsize=vmsize*sysconf(_SC_PAGESIZE)/1024;
cerr<<"vmsize is "<<vmsize<<endl;
struct rusage used;
getrusage(RUSAGE_CHILDREN,&used);
cerr<<"memory usage:"<<used.ru_minflt*sysconf(_SC_PAGESIZE)/1024<<endl;
}
int main()
{
srand((unsigned) time(NULL));
pid_t pid=fork();
if ( pid == -1)
{
cerr<<"error while forking"<<endl;
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
struct rlimit limit;
/* time limit */
limit.rlim_cur=limit.rlim_max=1;
setrlimit(RLIMIT_CPU,&limit);
/* memory limit */
limit.rlim_cur=limit.rlim_max=MEM * 1024;
setrlimit(RLIMIT_AS,&limit);
char *argv[]={(char *)"test",(char *)NULL};
execv(argv[0],argv);
cerr<<"failed to execv"<<endl;
exit(5);
}
else if (pid > 0)
{
int status,tmp,left_t;
struct timespec spec;
char pid_string[20];
pid_to_string(pid,pid_string);
get_timespec(&spec,OFFSET);
left_t = TIME;
while (1)
{
tmp = waitpid(pid,&status,WNOHANG);
if (tmp!=0) break;
/* check resource usage */
if ( (rand() % 100) < 100)
{
tmp = check_memory(pid_string);
if (tmp>0)
{
switch (tmp)
{
case 1 :cerr<<"time limit exceeded"<<endl;break;
case 2 :cerr<<"memory limit exceeded"<<endl;break;
}
kill(pid,SIGKILL);
break;
}
}
nanosleep(&spec,NULL);
left_t -= OFFSET;
if (left_t<=0)break;
}
tmp = check_memory(pid_string);
struct rusage used;
getrusage(RUSAGE_CHILDREN,&used);
printf("ru_maxrss:%ld\n",used.ru_maxrss);
printf("ru_ixrss:%ld\n",used.ru_ixrss);
printf("ru_idrss:%ld\n",used.ru_idrss);
printf("ru_isrss:%ld\n",used.ru_isrss);
printf("ru_minflt:%ld\n",used.ru_minflt);
printf("ru_majflt:%ld\n",used.ru_majflt);
printf("ru_nswap:%ld\n",used.ru_nswap);
printf("ru_inblock:%ld\n",used.ru_inblock);
printf("ru_oublock:%ld\n",used.ru_oublock);
cerr<<"memory usage:"<<used.ru_minflt*sysconf(_SC_PAGESIZE)/1024<<endl;
tmp = waitpid(pid,&status,WNOHANG);
if (tmp == 0)
{
kill(pid,SIGKILL);
cerr<<"time limit exceeded,killed"<<endl;
}
if (WIFEXITED(status))
{
cerr<<"child thread exit normally"<<endl;
cerr<<"child thread exit status is "<<WEXITSTATUS(status)<<endl;
}
else
{
cerr<<"child thread exit abnormally"<<endl;
if (WIFSIGNALED(status))
{
switch (WTERMSIG(status))
{
case SIGXCPU:cerr<<"SIGXCPU:time limit exceeded"<<endl; break;
case SIGXFSZ:cerr<<"SIGXFSZ:file size exceeded"<<endl; break;
case SIGSEGV:cerr<<"SIGSEGV:segmentation fault"<<endl; break;
default:cerr<<"caught signal "<<WTERMSIG(status)<<endl; break;
}
}
cerr<<"child thread exit status is "<<WEXITSTATUS(status)<<endl;
}
exit(EXIT_SUCCESS);
}
}