问题 Grand Central Dispatch(GCD)调度源标志


我最近改用了 kqueue的 至 GCD调度来源 监视文件更改。这已经很好地完成了,并且产生了一个更简单的API。我记录了我的开关 这里。我唯一的问题是,现在我无法访问我能够以kqueue进行的事件的标志。例如,使用kqueue,我能够检查文件是否已被删除,重命名,或者其属性是否已更改,具体如下:

struct kevent event;

...

if(event.flag & EV_DELETE)
{
    printf("File was deleted\n");
}

这个API不适用于GCD,还是我需要为每个我想听的标志设置调度源。或者最好使用kqueue,因为它为已发生的事件提供了更大的可见性。


3883
2017-10-13 02:18


起源

我实际上没有读过你的问题,但是我翻了一遍,所以你的名声可以是1337.好的,我现在就读它。 - morningstar


答案:


我找到了答案 并发编程指南。我第一次看到了 GCD参考 但没有运气。该指南的相关内容是

对于监视文件系统活动的描述符分派源,此函数返回一个常量,指示发生的事件类型。有关常量列表,请参阅dispatch_source_vnode_flags_t枚举类型。

以下是如何使用它的示例。

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);

8
2017-10-13 02:47



谢谢,这太棒了。我用你的那个 博客文章。但是,您应该更正第17行 [blockSelf watchStyleSheet:path]; 至 [blockSelf watchConfigFile:path];。 - Stéphane Bruckert
没有意义 source 成为 __block 因为它从未被分配给 - user102008


您可以将* dispatch_source_get_mask(source)*更改为* dispatch_source_get_data(source)*,因为dispatch_source_get_mask(source)返回您在创建处理程序时传递的所有标志,而不是生成的事件。


3
2017-09-10 14:19