2010-01-07 16 views
5

Estoy usando iPhone SDK 3.1.2, y el siguiente código muestra que NSOperationQueue no reutiliza el hilo para cada tarea.NSOperationQueue no reutilizar hilo en iPhone

El código no tiene ningún problema en Snow Leopard.

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

    // Override point for customization after app launch  
    [window addSubview:viewController.view]; 
    [window makeKeyAndVisible]; 

    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    [queue setMaxConcurrentOperationCount:1]; 
    for(int i = 0; i < 100; i++) { 
     NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; 
     [queue addOperation:op]; 
     [op release]; 
    } 
} 

- (void)run { 
    static int tc = 0; 
    if([[NSThread currentThread] isMainThread]) { 
     NSLog(@"MAIN THREAD"); 
     return; 
    } else if([[NSThread currentThread] name] == nil) { 
     [[NSThread currentThread] setName:[NSString stringWithFormat:@"THREAD_%d", tc++]]; 
    } 
    NSLog(@"%@", [[NSThread currentThread] name]); 
} 

La salida muestra que crea 100 hilos para ejecutar las 100 tareas.

2010-01-07 11:46:03.502 OperationQueueTest[7911:4503] THREAD_0 
2010-01-07 11:46:03.506 OperationQueueTest[7911:4d03] THREAD_1 
2010-01-07 11:46:03.507 OperationQueueTest[7911:4807] THREAD_2 
2010-01-07 11:46:03.510 OperationQueueTest[7911:4d07] THREAD_3 
2010-01-07 11:46:03.514 OperationQueueTest[7911:5007] THREAD_4 
2010-01-07 11:46:03.516 OperationQueueTest[7911:4f0b] THREAD_5 
2010-01-07 11:46:03.518 OperationQueueTest[7911:4e0f] THREAD_6 
... 
2010-01-07 11:46:03.740 OperationQueueTest[7911:4ea7] THREAD_97 
2010-01-07 11:46:03.744 OperationQueueTest[7911:4dcf] THREAD_98 
2010-01-07 11:46:03.746 OperationQueueTest[7911:460f] THREAD_99 
+0

me gustaría saber que así ... – gcamp

+0

¿Por qué importa si la cola es op hilos reutilización o no? –

+0

@Peter Hosey - supongo que no es la reutilización, pero el número máximo de hilo que está preocupado. Demasiados hilos enlazados a la CPU arruinarán tu rendimiento. – DougW

Respuesta

9

NSOperationQueue está diseñado para poner en común y reutilización de las discusiones en la forma más eficiente posible y en este caso, parece que decidió no volver a utilizar hilos fue el mejor camino a seguir.

Código de prueba tiene sus usos (y es posible que haya identificado un caso de esquina donde NSOperationQueue no hace la cosa más eficiente), pero eso no significa que NSOperationQueue siempre es terriblemente ineficiente cuando se trata de código real en vida real; de hecho, mi propia experiencia ha sido lo contrario.

Así que yo diría que lo usa en su código real y si tiene problemas de rendimiento, profundice en lo que está haciendo con los hilos detrás de las escenas. De lo contrario, no te preocupes por eso.

Como nota adicional, si todavía tiene curiosidad, puede intentar registrar los nombres de los hilos en una matriz de NSStrings y luego imprimir todo al final del código de prueba, en lugar de registrar a medida que avanza - esto reducirá significativamente la cantidad de trabajo realizado por cada NSInvocationOperation.

2

implementación de NSOperation/NSOperationQueue de Snow Leopard se basa ahora en GCD.

El iPhone sigue utilizando el antiguo aplicación leopardo. Por lo tanto, puede esperar resultados diferentes en cada plataforma (sin mencionar el hardware completamente diferente).

Es posible que el engendrar nuevos hilos sea la manera más eficiente de realizar las tareas que está dando a NSOperationQueue.

0

NSOperationQueue realiza sus operaciones agregadas de forma asincrónica (en una secuencia separada). Así que si es la impresión de la información de temas, entonces es posible que obtendremos mismo objeto hilo de la mayor parte del tiempo.

objeto NSOperation añadido en NSOperationQueue será diferentes pero de rosca objetos puede ser la misma.

- (void)operaitonqueueTest 
{ 

    _opQueue = [[NSOperationQueue alloc] init]; 
    [_opQueue setMaxConcurrentOperationCount:5]; 
    for(int i = 0; i < 50; i++) { 
     NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; 
     [_opQueue addOperation:op]; 
    } 
} 

- (void)run { 
    if([[NSThread currentThread] isMainThread]) { 
     NSLog(@"MAIN THREAD"); 
     return; 
    } 
    NSLog(@"currentThread = %@", [NSThread currentThread]); 
} 
Cuestiones relacionadas