2016-08-16 75 views
1

现在我正在用C++编程一个类似cron的调度程序。我的程序能够在特定时间开始工作并正确安排时间。 什么让我烦恼是检查过程是否仍然存在。启动过程并稍后识别

所以我有一个地图JobMap;其中充满了进程句柄作为键和作为值的作业。 我怎样才能把这两个值联系起来?我坚持的一点是,每当我尝试GetExitCodeProcess它永远不会返回STILL_ACTIVE。是否有可能为流程设置唯一的令牌/密钥,以便我可以识别它并将其与工作联系起来?

任何想法将是一个很大的帮助,非常感谢!

void Cron::CheckRunningJobs() 
{ 
    DatNowObj Today; 
    DWORD exitCode = 0; 

    // now iterate through the executed jobs and check their state 
    for(MC_STL_PTR(MapPtr,JobMap)) //MapPtr is a pointer for my map 
    { 
     DatStrNowObj Today; //gives actual date 
     DWORD exitCode = 0; 
     PROT()<<"Job Handle:"<<MapPtr->first <<"Job in Map: "<<MapPtr->second.Job->getDescription()<<endl; 

     // store the exit code for later use 
     MapPtr->second.exitCode = GetExitCodeProcess(MapPtr->first, &exitCode); 
     if(GetExitCodeProcess(MapPtr->first, &exitCode) == STILL_ACTIVE) 
     { 
      PROT()<<"PROCESS STILL ACTIVE"<<endl; 
     } 
     else if(GetExitCodeProcess(MapPtr->first, &exitCode) == ERROR_INVALID_FUNCTION) 
     { 
      CloseHandle(MapPtr->first); 
      continue; 
     } 
     else if(MapPtr->second.execTime) 
     { 

     } 
     else if(GetExitCodeProcess(MapPtr->first, &exitCode) == 0) 
     { 
      CloseHandle(MapPtr->first); 

      JobMap.erase(MapPtr); 

      PROT()<<"Job in Map after Erase: "<<MapPtr->second.Job->getDescription() << "and Map size: " << JobMap.size()<<endl; 
      continue; 
     } 
     else 
     { 
      PROT()<<"Error:"<<GetLastError()<<endl; 
      continue; 
     } 

    } 
} 
+0

对你的'CreateProcess'形式的句柄做一个'WaitForSingleObject'(在你的情况下它似乎是'MapPtr-> first')。 –

+0

MapPtr-> first是从CreateProcess存储的HANDLE。 WaitForSingleObject不会阻塞其他进程吗?我的意思是如果我有2个同时开始的工作。 –

+0

它不会阻止其他进程,而是阻止您的进程(在您称之为的线程中)。所以你要么在一个单独的线程中等待每个线程,要么使用一个专用线程来等待,为所有“当前”句柄调用“WaitForMultipleObjects”。当然,后者涉及一些跨线程通信,用于传递新进程的句柄,并通知进程中某些其他代码/线程某些进程已完成。 –

回答

2

请阅读the documentationuser6545984链接。你似乎在这里变得非常混乱。

GetExitCodeProcess()返回一个BOOL,指示函数是否成功,而不是过程。您正在尝试使用常数与BOOL进行比较,就好像它是exitCode一样。但它们是不兼容的类型。即使它们不是,我也不知道为什么你会一遍又一遍地调用函数!

要获得退出代码,您需要传入一个LPDWORD指针来接收它。调用函数一次,得到两个输出到右侧变量 - 一个返回值,一个输出参数 - 并对这些进行适当的响应。

所以,您需要更改至少这

MapPtr->second.exitCode = GetExitCodeProcess(MapPtr->first, &exitCode); 

喜欢的东西

BOOL result = GetExitCodeProcess(MapPtr->first, &MapPtr->second.exitCode); 

或其他任何地方,你想存储所说的代码 - 然后更新所有的比较匹配,也如果需要,请将其与result相比较。

+2

+1 @Majid D. L.只要确保你明白'GetExitCodeProcess'会立即返回*如果进程是'STILL_ACTIVE'。所以要么不时调用你的函数,要么同时做其他事情,要么使用'WaitForSingleObject'或'WaitForMultipleObjects'方法。您不想(意外地)写一个“busyloop”,它将重复轮询针对仍在运行的进程的退出代码。 –

+0

非常感谢!这对我有帮助。我有点盲目地看到它,认为它会直接返回Exitcode。 –

+0

@ MajidD.L。别客气。如果这可以帮助你,请注册。如果它回答您的问题,请使用勾号将其标记为答案。 –

0
BOOL WINAPI GetExitCodeProcess(
    _In_ HANDLE hProcess, 
    _Out_ LPDWORD lpExitCode 
); 

它并不直接返回退出代码。了解更多信息GetExitCodeProcess

+0

感谢您的回答,我可能会错误地使用它。 –

+0

在你的回答中值得一提的是返回的'BOOL'所做的:表示_function_是否成功。 –