Using Operation Queues for Concurrency
来源:互联网 发布:英语 伴读软件 编辑:程序博客网 时间:2024/05/17 02:43
Using Operation Queues for Concurrency
You have implemented a concurrent program using threads and a concurrent operation, so now you will implement a program that uses operations and an operation queue for concurrency. This program contains the same functionality of the ConcurrentThreads program that you implemented earlier in this chapter. This will enable you to compare the use of the different APIs and mechanisms for concurrent programming.
In Xcode, create a new project by selecting New Project . . .from the Xcode File menu. In the New Project Assistant pane, create a command-line application. In the Project Optionswindow, specify ConcurrentOperations for the Product Name, choose Foundation for the Project Type, and select ARC memory management by checking the Use Automatic Reference Counting check box. Specify the location in your file system where you want the project to be created (if necessary, select New Folder and enter the name and location for the folder), uncheck the Source Control check box, and then click the Create button.
Next you will create the custom operation class. Select New File . . . from the Xcode File menu, select the Objective-C class template, and name the class ConcurrentProcessor. Make the class a subclass of NSOperation, select theConcurrentOperations folder for the files location and theConcurrentOperations project as the target, and then click theCreate button. In the Xcode project navigator pane, select theConcurrentProcessor.m file and update the interface, as shown in Listing 17-21.
Listing 17-21. ConcurrentProcessor Interface
#import <Foundation/Foundation.h>@interface ConcurrentProcessor : NSOperation@property (readonly) NSUInteger computations;- (id)initWithData:(NSInteger *)result computations:(NSUInteger)computations;@end
The interface contains one property named computations and a single initialization method. The interface is a subclass ofNSOperation, as required for a custom operation class. Thecomputations property specifies the number of computations the operation will perform. In the Xcode project navigator, select theConcurrentProcessor.m file and update the implementation, as shown in Listing 17-22.
Listing 17-22. ConcurrentProcessor Implementation
#import "ConcurrentProcessor.h"@implementation ConcurrentProcessor{ NSInteger *computeResult;}- (id)initWithData:(NSInteger *)result computations:(NSUInteger)computations{ if ((self = [super init])) { _computations = computations; computeResult = result; } return self;}- (void)main{ @autoreleasepool { @try { if (![self isCancelled]) { NSLog(@"Performing %ld computations", self.computations); [NSThread sleepForTimeInterval:1.0]; for (int ii=0; ii<self.computations; ii++) { *computeResult = *computeResult + 1; } } } @catch (NSException *ex) {} }}@end
The implementation begins by declaring a private instance variable,computeResult, which contains the address of the memory location where the computation result is stored. The init: method sets the computations property and computeResult variable to the input parameters. The main method performs the compute task for the operation. It includes an autorelease pool and a try-catch block, as recommended for thread-based execution of operation objects. The main method also checks if the operation is cancelled in order to quickly terminate its execution if it is no longer needed. The computation logic simply increments the computation result for the number of computations specified. Notice here that, unlike with the concurrent operation shown in Listing 17-19 (theGreetingOperation program), thread execution state (i.e.,isFinished and isExecuting) is not updated. This is performed automatically by the operation queue. Also note that, unlike the thread-based ConcurrentProcessor implementation (as shown inListing 17-14), synchronization mechanisms are not required. This is due to the fact that interoperation dependencies can be declared. These prevent operations from concurrently accessing shared data and also synchronize the order that operations are executed.
Now let’s move on to the main() function. In the Xcode project navigator, select the main.m file and update the main() function, as shown in Listing 17-23.
Listing 17-23. ConcurrentOperations main( ) Function
#import <Foundation/Foundation.h>#import "ConcurrentProcessor.h"int main(int argc, const char * argv[]){ @autoreleasepool { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSInteger result = 0; // Create operation objects ConcurrentProcessor *proc1 = [[ConcurrentProcessor alloc]initWithData:&result computations:5]; ConcurrentProcessor *proc2 = [[ConcurrentProcessor alloc]initWithData:&result computations:10]; ConcurrentProcessor *proc3 = [[ConcurrentProcessor alloc]initWithData:&result computations:20]; NSArray *operations = @[proc1, proc2, proc3]; // Add inter-operation dependencies [proc2 addDependency:proc1]; [proc3 addDependency:proc2]; // Add operations to queue to start execution [queue addOperations:operations waitUntilFinished:NO]; // Wait until all operations are finished, then display result [queue waitUntilAllOperationsAreFinished]; NSLog(@"Computation result = %ld", result); } return 0;}
The method begins by creating an operation queue and the variable, computeResult, which holds the result of the computation for the operations. Then three operation objects are created, each performing a different number of computations, and these are combined in an NSArray instance. Next, dependencies between the operations are defined. In this case, operation 1 (proc1) must complete before operation 2 (proc2), and operation 2 must complete before operation 3 (proc3). The operations are then added to the queue to begin asynchronous execution. The code waits until all of the operations have finished execution and then logs the computation result to the output pane.
When you compile and run the program, you should observe the messages in the output pane shown in Figure 17-7.
Figure 17-7. ConcurrentOperations program output
The results are identical to that obtained with the thread-based version of this program, with considerably less code complexity. This program demonstrates how operation objects and queues can greatly simplify concurrent programming. In effect, they enable you to execute tasks asynchronously and concurrently without having to perform low-level thread-based programming, and manage the resulting complexity. They enable you to manage dependencies among various operations, cancel or suspend them, and provide a higher-level, object-oriented abstraction for concurrent programming. In the next section, you will explore Grand Central Dispatch, a C-based mechanism for asynchronous/concurrent programming.
- Using Operation Queues for Concurrency
- Concurrency Programming Guide 并发设计指引(五) Operation Queues
- Operation Queues
- Concurrent Programming 6:Using Threads for Concurrency
- Using BASH for network socket operation
- Objective-C Operation Queues
- Operation Queues并发编程
- Using Timer Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- Implement Stack using Queues
- 二次开发之 自定义函数
- 使用paoding lucene分词和网页爬虫实现的简易网页搜索
- nmap命令使用详解
- ckeditor文本编辑器插件上传功能与struts2的结合
- 使用mysql作为hive的元数据库
- Using Operation Queues for Concurrency
- php urlencode与rawurlencode的区别
- shell: ip合法性检查
- android 多媒体框架中mediaplay与opencore的衔接调用过程
- C++智能指针的非智能
- IMEI第15位的生成算法SQL函数版
- mysql schema设计优化
- jacob_liang系统平台统一用户 一个开源框架
- TCP滑动窗口协议