If I have a serial queue, how can I, from the main thread, tell it to immediately stop execution and cancel all of its tasks?
There is no way to empty pending tasks from a dispatch queue without implementing non-trivial logic yourself as of iOS 9 / OS X 10.11.
If you have a need to cancel a dispatch queue, you might be better off using NSOperationQueue
which offers this and more. For example, here's how you "cancel" a queue:
NSOperationQueue* queue = [NSOperationQueue new];
queue.maxConcurrentOperationCount = 1; // make it a serial queue
...
[queue addOperationWithBlock:...]; // add operations to it
...
// Cleanup logic. At this point _do not_ add more operations to the queue
queue.suspended = YES; // halts execution of the queue
[queue cancelAllOperations]; // notify all pending operations to terminate
queue.suspended = NO; // let it go.
queue=nil; // discard object