ACE进程管理

来源:互联网 发布:删除三星预装软件 编辑:程序博客网 时间:2024/05/18 03:19

1、使用ACE_Process派生进程

1.1使用ACE_Process派生进程需要两个步骤:

  1. 实例化一个ACE_Process_Options对象,为新创建的进程指定属性:
    1. 设置标准I/O句柄(标准输入、标准输出、标准错误输出,可进行输入输出重定向);
    2. 指定父子进程句柄继承方式;
    3. 设置子进程的环境变量和命令行;
    4. 在Windows上设置安全属性,在UNIX上设置uid/gid/euid。
  2. 调用ACE_Process::spawn()方法派生新进程。

1.2注意,ACE_Process::spawn()方法不是fork()

ACE_Process::spawn()方法类似于UNIXsystem()调用,而不是fork()。如果我们非要使用fork(),可以调用ACE_OS::fork()

1.3 ACE_Process::prepare()挂钩方法

一般情况下,我们可以先实例化一个ACE_Process_Options对象,然后调用ACE_Process_Options::command_line()方法设置命令行。在调用ACE_Process::spawn()方法时把设置好的ACE_Process_Options对象传进去,派生子进程。代码如下:

[cpp] view plaincopyprint?

1.  ACE_Process_Options options;  

2.  options.command_line ("/usr/bin/ls -l");  

3.    

4.  ACE_Process process;  

5.  pid_t pid = process.spawn (options);  

6.    

7.  process.wait ();  

在创建新进程之前,ACE_Process::spawn()方法会调用进程对象的ACE_Process::prepare()挂钩方法。因此,如果不在外面设置新进程属性,我们也可以在ACE_Process::prepare()挂钩方法中初始化新进程属性。

ACE_Process::prepare()的返回值是有用的,如果返回0,则spawn()继续创建新进程,如果prepare()返回-1spawn则放弃创建新进程。

1.4 ACE_Process其它挂钩方法

1parent (pid_t child),在fork()完成后,此挂钩方法会立刻在父进程中被回调;

2child (pid_t parent),在fork()完成后,后续的exec()被调用前,此挂钩方法会在子进程中被回调,此时新的环境还没有被设置。在Windows上这个函数不会被调用。

2、使用ACE_Process_Manager派生进程

 

2.1 ACE_Process_Manager提供的新特性

  • ACE_Process_Manager允许用户通过单次spawn_n()调用派生多个进程。
  • ACE_Process_Manager有子进程计数,因此可以通过不带参数的wait()调用等待所有子进程。
  • 可以通过调用terminate(pid_t child_pid)强制终止某个子进程。
  • 能够与ACE_Reactor框架协同工作。

2.2 ACE_Process_Manager的使用方法

ACE_Process使用方法类似,首先实例化一个ACE_Process_Options对象,设置新进程属性,并将此对象传递给ACE_Process_Manager::spawn_n()方法,派生多个子进程。可以调用terminate()方法终止某个子进程,可以调用wait()等待某个或所有子进程。

2.3 ACE_Process_ManagerACE_Reactor的集成

一般情况下,主进程创建子进程后,还需要完成自己的工作,不能单纯的调用wait,阻塞的等待子进程的退出。通过与ACE_Reactor的集成,主进程在创建子进程后可继续自己的工作,在子进程退出时,再由Reactor框架通过调用ACE_Event_Handler::handle_exit(ACE_Process *process)完成子进程的资源回收。下面是一个例子:

[cpp] view plaincopyprint?

1.  #include <ace/Event_Handler.h>  

2.  #include <ace/Reactor.h>  

3.  #include <ace/Process_Manager.h>  

4.    

5.  const int NCHILDREN = 10;  

6.    

7.  // Handle child process exit  

8.  class ProcessCleaner: public ACE_Event_Handler {  

9.      public:  

10.         ProcessCleaner (): count_(0) {}  

11.           

12.         virtual int handle_exit (ACE_Process *process) {  

13.             ACE_DEBUG ((LM_DEBUG,  

14.                         ACE_TEXT ("[%d]Process %d exit with exit code %d\n"),  

15.                         count_,  

16.                         process->getpid (),  

17.                         process->return_value ()));  

18.             if (++count_ == NCHILDREN)  

19.                 ACE_Reactor::instance ()->end_reactor_event_loop ();  

20.         }  

21.     private:  

22.         int count_;  

23. };  

24.   

25. int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) {  

26.     // Instantiate a process manager with space for  

27.     // NCHILDREN processes.  

28.     ACE_Process_Manager pm (NCHILDREN, ACE_Reactor::instance ());  

29.   

30.     // Create a child process exit handler.  

31.     ProcessCleaner pc;  

32.   

33.     // Specify the process options  

34.     ACE_Process_Options options;  

35.     options.command_line (ACE_TEXT ("/bin/date"));  

36.   

37.     // Spawn NCHILDREN processes.  

38.     pid_t pids[NCHILDREN];  

39.     pm.spawn_n (NCHILDREN, options, pids);  

40.   

41.     // Register handler to be called when these processes eixt.  

42.     for (int i = 0; i < NCHILDREN; i++)  

43.         pm.register_handler (&pc, pids[i]);  

44.   

45.     // Run the event loop  

46.     ACE_Reactor::instance ()->run_reactor_event_loop ();  

47. }  


原创粉丝点击