Grand Central Dispatch(GCD)调度源标志
我最近从使用kqueue切换到GCD调度源来监视文件更改。 这个工作得很好,并导致了一个更简单的API。 我在这里logging了我的开关。 我唯一的问题是,现在我不能访问我能够在kqueue事件的标志。 例如对于kqueue,我能够检查文件是否被删除,重命名,或者它的属性被改变了如下:
struct kevent event; ... if(event.flag & EV_DELETE) { printf("File was deleted\n"); }
这个API不适用于GCD吗?还是需要为每个我想听的标志设置调度源。 或者最好使用kqueue,因为它提供了对发生的事件更大的可见性。
我在“ 并发编程指南”中find了答案。 我第一次看了GCD参考书,但没有运气。 指南的相关行是
对于监视文件系统活动的描述符调度源,此函数返回一个常数,指示发生的事件的types。 有关常量的列表,请参见dispatch_source_vnode_flags_t枚举types。
这里是一个如何使用它的例子。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); int fildes = open("path/to/some/file", O_EVTONLY); __block dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fildes, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, queue); dispatch_source_set_event_handler(source, ^ { unsigned long flags = dispatch_source_get_mask(source); if(flags & DISPATCH_VNODE_DELETE) printf("DISPATCH_VNODE_DELETE\n"); if(flags & DISPATCH_VNODE_WRITE) printf("DISPATCH_VNODE_WRITE\n"); if(flags & DISPATCH_VNODE_EXTEND) printf("DISPATCH_VNODE_EXTEND\n"); if(flags & DISPATCH_VNODE_ATTRIB) printf("DISPATCH_VNODE_ATTRIB\n"); if(flags & DISPATCH_VNODE_LINK) printf("DISPATCH_VNODE_LINK\n"); if(flags & DISPATCH_VNODE_RENAME) printf("DISPATCH_VNODE_RENAME\n"); if(flags & DISPATCH_VNODE_REVOKE) printf("DISPATCH_VNODE_REVOKE\n"); }); dispatch_source_set_cancel_handler(source, ^(void) { close(fildes); }); dispatch_resume(source);
您可以将* dispatch_source_get_mask(source)*更改为* dispatch_source_get_data(source)*,因为dispatch_source_get_mask(source)返回您在创build处理程序时所传递的所有标志,而不是生成的事件。