2016-01-05 45 views
0

考慮下面的類:目標C線程/ Runloop /併發考慮

@interface TaskScheduler() 

@property (strong) NSMutableDictionary *tasks; 

@end 

@implementation TaskScheduler 

- (void)addTask:(Task *)task 
{ 
    [_tasks setObject:task forKey:task.id]; 
} 

- (void)cancelTask:(NSString *)id 
{ 
    [_tasks removeObjectForKey:id]; 
} 

- (void)runTask:(Task *)task 
{ 
    // run task in a background concurrent global dispatch queue 
    dispatch_queue_t backgroundConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 

    void (^dispatchBlock)() = ^void(){ 
     BOOL success = task.taskBlock(); // typedef BOOL (^TaskBlock)(); 
     if (success) 
     { 
      [self cancelTask:task.id]; 
     } 
    }; 
    dispatch_async(backgroundConcurrentQueue, dispatchBlock); 
} 

- (void)didUpdateSystemUpdateValue 
{ 
    // some other class has a `dispatch_source_t` timer that fires every second and calls this delegate API 

    if (shouldRunTask) 
    { 
     for (Task *task in _tasks.allValues) 
     { 
      [self runTask:task]; 
     } 
    } 
} 

@end 

現在請注意,我如何取消調度隊列塊內任務調用本身。

我在這裏有點困惑 - runTask:調用中是否有任何問題?如果它在使用全局調度隊列運行的dispatchBlock內成功,我將取消該任務。只有tasks內的任務才能運行。

唯一的問題是我可以看到,如果某些條件成立,同一任務可以運行多次,除非任務在其中一個調度調用中成功後,它將不會存在於隊列中(或字典任務)。

編輯:我已經改變了原來的問題。我從來沒有打算讓其餘的設計成爲問題的一部分。這個問題可以在沒有最新改變的情況下回答,但以防萬一。

+0

我想你需要給我們更多的代碼。就目前而言,你的榜樣沒有什麼意義。例如,你聲明一個名爲'tasks'的'NSMutableDictionary',然後你不使用它。您可以將任務添加到名爲'_tasks'的字典中,該字典在其他任何地方都不會被引用。取消任務只會從字典中刪除任務,但除此之外別無其他。任務如何開始? 'addTask'有什麼意義?爲什麼在成功完成任務後取消任務? – mttrb

+0

通過'addTask''(主線程,大概)和'cancelTask​​''(後臺線程)'從多線程訪問'_tasks'是一個好主意。當'taskBlock()'完成時,你應該在主隊列中發送另一個塊來調用'cancelTask​​'。 –

+0

也許你可以退後一步並描述你想在這裏完成的任務(並幫助我們理解基本調度隊列和/或操作隊列不足的原因)。也許用你預期如何使用你的任務調度器的實際例子來編輯這個問題。 – Rob

回答

3

你似乎是假設它是安全的-setObject:forKey:-removeObjectForKey:從兩個不同的線程同時調用,這是斷然安全。您需要額外的同步。事實上,您將-removeObjectForKey:呼叫包裹在您的-cancelTask:方法中,並且從您的-runTask:方法調用它是無關緊要的。 NSMutableDictionary對於來自多個線程的併發操作是不安全的,無論其中包含多少個其他方法,如果這些包裝方法中沒有一個提供任何同步,而這些方法都不在這裏進行復制。

+0

我明白了。所以如果我提供一個安全的'NSMutableDictionary'實現,我不會有任何明顯的問題。 – p0lAris

+0

理論上,是的。 – ipmcc

+0

我明白了。非常感謝你。 – p0lAris