1.CGD监视进程

GCD可以检测进程的运行,退出状态,可以检测到进程间的信号。

#define DISPATCH_PROC_EXIT		0x80000000
#define DISPATCH_PROC_FORK		0x40000000
#define DISPATCH_PROC_EXEC		0x20000000
#define DISPATCH_PROC_SIGNAL	   0x08000000

可以使用dispatch source捕获相关信号。

  • DISPATCH_PROC_EXITMac上可以捕获,在iOS上是无法捕获的。
  • DISPATCH_PROC_SIGNALMac/iOS上均可捕获。

2.Mac代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 可以通过注释掉的代码找关掉应用的BundleIdentifier
//    NSArray *runningAppList = [NSWorkspace sharedWorkspace].runningApplications;
//    
//    NSLog(@"runningAppList = %@",runningAppList.description);
    
    NSArray *appList = [NSRunningApplication
                                  runningApplicationsWithBundleIdentifier:@"com.google.Chrome"];
    
    if (appList.count == 0 ) {
        return;
    }
    
    NSRunningApplication *chromeApp = appList[0];

    self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, chromeApp.processIdentifier,
                                         DISPATCH_PROC_EXIT, DISPATCH_TARGET_QUEUE_DEFAULT);
    dispatch_source_set_event_handler(self.source, ^(){
        NSLog(@"google Chrome exit");
    });
    dispatch_resume(self.source);
    

执行上述代码前,确保google Chrome浏览器是打开的,然后,退出google Chrome浏览器

1
2
3

2014-09-06 16:16:34.261 MacSignalTest[4070:1003] google Chrome exit
    

3. iOS代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

    pid_t pid = getpid();
    pid_t uid = getuid();
    const char* name =  getprogname();
    
    NSLog(@"pid = %d uid = %d, progname = %s",pid,uid,name);
    
    self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid,
                                         DISPATCH_PROC_SIGNAL, DISPATCH_TARGET_QUEUE_DEFAULT);
    dispatch_source_set_event_handler(self.source, ^(){
        NSLog(@"ios app exit for signal!");
    });
    dispatch_resume(self.source);
    

signal信号发出时,会触发signal事件。

1
2