Esempio n. 1
0
void JudgeThread::operator()()
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);

    OJString infoBuffer;
    FormatString(infoBuffer, OJStr("work/%d"), id_);
    FileTool::MakeDir(infoBuffer);

    FormatString(infoBuffer, OJStr("[JudgeThread][%d]start..."), id_);
    logger->logTrace(infoBuffer);

    while (!g_sigExit)
    {

        IMUST::TaskPtr pTask;

        //从任务队列取任务
        workingTaskMgr_->lock();
        if(workingTaskMgr_->hasTask())
        {
            pTask = workingTaskMgr_->popTask();
        }
        workingTaskMgr_->unlock();

        if(!pTask)//没有任务
        {
            OJSleep(1000);
            continue;
        }

        pTask->init(id_);
        if(!pTask->run())
        {
            FormatString(infoBuffer, 
                OJStr("[JudgeThread][%d]System Error!Judge thread will exit!"), id_);
            logger->logError(infoBuffer);
            break;
        }

        //添加到完成队列
        finisheTaskMgr_->lock();
        finisheTaskMgr_->addTask(pTask);
        finisheTaskMgr_->unlock();

        OJSleep(10);//防止线程过度繁忙
    }

    FormatString(infoBuffer, OJStr("[JudgeThread][%d]end."), id_);
    logger->logTrace(infoBuffer);

}
Esempio n. 2
0
void JudgeDBRunThread::operator()()
{
    IMUST::ILogger *logger = IMUST::LoggerFactory::getLogger(IMUST::LoggerId::AppInitLoggerId);
    logger->logTrace(GetOJString("[DBThread] thread start..."));

    while(!g_sigExit)
    {
        if(!dbm_->run())
        {
            logger->logError(GetOJString("[DBThread] db manager was dead!"));
            break;
        }
        OJSleep(100);
    }

    logger->logTrace(GetOJString("[DBThread] thread end."));
}
Esempio n. 3
0
/* 延迟删除文件。
当某子进程尚未完全退出时,他占用的文件再次被打开或删除,都会失败。故作延迟,等待一段时间。
如果文件始终无法删除,将表示该子进程无法退出,这将是一个致命错误,评判线程应当结束。 */
bool safeRemoveFile(const OJString & file)
{
    OJString infoBuffer;

    for(OJInt32_t i=0; i<10; ++i)//尝试删除10次
    {
        if(FileTool::RemoveFile(file))
        {
            return true;
        }
        OJSleep(1000);

        FormatString(infoBuffer, OJStr("safeRemoveFile '%s' faild with %d times. code:%d"), 
            file.c_str(), i+1, GetLastError());
        LoggerFactory::getLogger(LoggerId::AppInitLoggerId)->logError(infoBuffer);
    }

    return false;
}
OJInt32_t WindowsProcess::start()
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);

    //加到作业中
	if (!jobHandle_.assinProcess(processHandle_))
    {
        logger->logErrorX(OJStr("[process] - can't assign process to job! error:%u"), GetLastError());
        kill();
        return -1;
    }

    //启动线程
    ResumeThread(threadHandle_);
    
    //关闭不使用的句柄。让进程执行完毕后立即退出。
    SAFE_CLOSE_HANDLE_AND_RESET(threadHandle_);
    SAFE_CLOSE_HANDLE_AND_RESET(inputFileHandle_)
    SAFE_CLOSE_HANDLE_AND_RESET(outputFileHandle_)

    result_ = AppConfig::JudgeCode::Accept;

	DWORD ExecuteResult = -1;  
	ULONG completeKey;  
	LPOVERLAPPED processInfo;  
	bool done = false;  
	while(!done)  
	{
        if(!jobHandle_.getState(ExecuteResult, completeKey, processInfo))
        {
            DEBUG_MSG(OJStr("get job State faild!"));
            OJSleep(1);
            continue;
        }

        DWORD dwCode = (DWORD)processInfo;

		switch (ExecuteResult)   
		{  
		case JOB_OBJECT_MSG_NEW_PROCESS:    
            //DEBUG_MSG_VS(OJStr("[WindowsProcess]new process: %u"), dwCode);
			break;

		case JOB_OBJECT_MSG_END_OF_JOB_TIME: //job超时
            DEBUG_MSG(OJStr("[WindowsProcess]Job time limit reached")); 
            result_ = AppConfig::JudgeCode::TimeLimitExceed;  
			done = true;  
			break;

		case JOB_OBJECT_MSG_END_OF_PROCESS_TIME:   //线程超时
			DEBUG_MSG(OJStr("[WindowsProcess]process time limit reached"));
            result_ = AppConfig::JudgeCode::TimeLimitExceed;
			done = true;  
			break;

		case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:   //进程内存超限
            DEBUG_MSG(OJStr("[WindowsProcess]Process exceeded memory limit"));  
            result_ = AppConfig::JudgeCode::MemoryLimitExceed;  
			done = true;  
			break;

        case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: //job内存超限
            {
                OJInt32_t mem = getRunMemory();  
                DebugMessage(OJStr("[WindowsProcess]exceeded job memory limit with %dkb"), mem);
                result_ = AppConfig::JudgeCode::MemoryLimitExceed; 
                done = true;  
            }
			break;  

		case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:  //超出运行的进程数量
            DEBUG_MSG(OJStr("[WindowsProcess]Too many active processes in job"));
            result_ = AppConfig::JudgeCode::RuntimeError;
            done = true;
			break;

		case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:  
            DEBUG_MSG(OJStr("[WindowsProcess]Job contains no active processes")); 
			done = true;  
			break;

		case JOB_OBJECT_MSG_EXIT_PROCESS: //进程退出
            //DEBUG_MSG_VS(OJStr("[WindowsProcess]Process %u exit."), dwCode);
            if(::GetProcessId(processHandle_) == dwCode)
			{
                done = true;
            }
			break;  

		case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: //进程异常结束
            DEBUG_MSG(OJStr("[WindowsProcess]Process terminated abnormally"));
            result_ = AppConfig::JudgeCode::RuntimeError;  
			done = true;  
			break;  

		default:  
            DEBUG_MSG(OJStr("[WindowsProcess]Unknown notification"));
            result_ = AppConfig::JudgeCode::UnknownError; 
			break;
		}
	}  
    
    {
        FILETIME ftime, temp;
        ::GetProcessTimes(processHandle_, &temp, &temp, &temp, &ftime);

        ULARGE_INTEGER time2;
        time2.LowPart = ftime.dwLowDateTime;
        time2.HighPart = ftime.dwHighDateTime;

        runTime_ = time2.QuadPart / 10000;
    }
    
    {
        PROCESS_MEMORY_COUNTERS info;
        ::GetProcessMemoryInfo(processHandle_, &info, sizeof(info));

        runMemory_ = info.PeakPagefileUsage;
    }

    while(!jobHandle_.terminate())//强制关闭作业
    {
        DEBUG_MSG(OJStr("Terminate job faild!"));
        OJSleep(10);
    }

    alive_ = false;//进程结束

    //正常退出。即不是超时等状况。
    if(result_ == AppConfig::JudgeCode::Accept)
    {
        DWORD code = getExitCode();//获取进程返回值,以判断进程是否执行成功。
        if(code != 0)
        {
            result_ = AppConfig::JudgeCode::RuntimeError;
            DEBUG_MSG_VS(OJStr("process exit with code : %u, last error: %u"), 
                code, GetLastError());
        }
    }

    SAFE_CLOSE_HANDLE_AND_RESET(processHandle_);

	return 0;  
}