obj-c利用dispatch库并发示例

来源:互联网 发布:php数组删除重复值 编辑:程序博客网 时间:2024/05/16 06:30

我们首先写一个纯C的程序,代码的功能为显示指定范围整数中素数的个数:

#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <math.h>#include <time.h>#include <unistd.h>typedef unsigned long long ULL;bool is_prime(x){    ULL j = sqrtl(x + 1);    if(x==2) return true;    if(x<2 || x%2 == 0) return false;    for(ULL i = 3;i<=j;i = i+2){        if(x%i == 0) return false;    }    return true;}ULL p_count(ULL start,ULL end){    ULL count = 0;    for(ULL i = start;i<=end;i++){        if(is_prime(i)) count++;    }    return count;}bool is_neg_num_ll(long long x){    if(x < 0)        return true;    else        return false;}int main(int argc,char **argv){    ULL start_x,end_x;    if(argc <=1){        printf("usage : %s [start_num] end_num\n",argv[0]);        return 1;    }    if(argc == 2){        sscanf(argv[1],"%llu",&end_x);        if(is_neg_num_ll((long long)end_x)){            printf("end_num %llu must not neg num!\n",end_x);            return 2;        }        start_x = 0;    }    if(argc == 3){        sscanf(argv[1],"%llu",&start_x);        sscanf(argv[2],"%llu",&end_x);        if(is_neg_num_ll((long long)start_x) || is_neg_num_ll((long long)end_x)){            printf("start_num %llu or end_num %llu must not neg num!\n",\                start_x,end_x);            return 3;        }        if(start_x >= end_x){            printf("start_num %llu must < end_num %llu\n",start_x,end_x);            return 4;        }    }    printf("notice:calc from %llu to %llu\n",start_x,end_x);    int begin = clock();    ULL count = p_count(start_x,end_x);    double stop = ((1.0 * (clock() - begin)) / CLOCKS_PER_SEC) * 1000.0;    printf("in range (%llu - %llu) p_count is %llu (take %f ms)\n",start_x,end_x,count,stop);    return 0;}

代码很简单,如果只指定一个参数end,则返回0-end中素数个数,如果指定2个参数start和end则返回(start-end)中素数的个数(包含start和end在内)。
下面引入dispatch机制,我们看看并发操作怎么写:

#import <Foundation/Foundation.h>//#include "/usr/local/include/dispatch/dispatch.h"typedef unsigned long long ULL;typedef struct {    ULL start;    ULL end;}range_t,*prange_t;bool is_prime(x){    ULL j = sqrtl(x + 1);    if(x==2) return true;    if(x<2 || x%2 == 0) return false;    for(ULL i = 3;i<=j;i = i+2){        if(x%i == 0) return false;    }    return true;}ULL p_count(ULL start,ULL end){    ULL count = 0;    for(ULL i = start;i<=end;i++){        if(is_prime(i)) count++;    }    return count;}range_t get_range(int index){    switch(index){        case 0:            return (range_t){1,10000};        case 1:            return (range_t){10001,20000};        case 2:            return (range_t){20001,30000};        case 3:            return (range_t){30001,40000};    }    return (range_t){-1,-1};}static ULL g_count = 0;static NSNumber *g_lock_count = nil;void callback(void *context){    prange_t pr = context;    NSLog(@"range : (%llu - %llu)",pr->start,pr->end);    ULL count = p_count(pr->start,pr->end);    @synchronized(g_lock_count){        g_count += count;    }}void function_way(void){    g_lock_count = @1;    range_t range_ary[4] = {{1,100000},{100001,200000},{200001,300000},{300001,400000}};    //FIXME:dispatch_queue_create make crash!!!    dispatch_queue_t queue = dispatch_queue_create("WorkBlocks",NULL);    //dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);    dispatch_group_t group = dispatch_group_create();///*    for(int i = 0;i<4;i++){        dispatch_group_async_f(group,queue,&range_ary[i],callback);    }    dispatch_group_wait(group,DISPATCH_TIME_FOREVER);//*/        //dispatch_release(queue);    NSLog(@"at last! count is %llu",g_count);}void apply_way(void){    dispatch_queue_t queue = dispatch_queue_create("WorkBlocks",NULL);    ULL __block last_count = 0;    NSNumber *lock_count = @2;    dispatch_apply(4,queue,^(size_t i){        range_t r = get_range(i);        NSLog(@"IDX:%lu:range is (%llu - %llu)",i,r.start,r.end);        ULL count = p_count(r.start,r.end);        @synchronized(lock_count){            last_count += count;        }    });    NSLog(@"at last! count is %llu",last_count);}void group_way(void){    NSNumber *lock_index = @1;    NSNumber *lock_count = @2;    ULL __block last_count = 0;    int __block work_index = 0;    //range_t range_ary[4] = {{1,100},{101,200},{201,300},{301,400}};    //FIXME:dispatch_queue_create make crash!!!    dispatch_queue_t queue = dispatch_queue_create("WorkBlocks",NULL);    //dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);    dispatch_group_t group = dispatch_group_create();///*    dispatch_block_t task = ^(void){        int index = work_index;        NSLog(@"my work index is %d",index);        @synchronized(lock_index){            ++work_index;        }        range_t r = get_range(index);        ULL count = p_count(r.start,r.end);        @synchronized(lock_count){            last_count += count;        }    };    for(int i = 0;i<4;i++){        dispatch_group_async(group,queue,task);    }    dispatch_group_wait(group,DISPATCH_TIME_FOREVER);//*/        //dispatch_release(queue);    NSLog(@"at last! count is %llu",last_count);}int main(void){    @autoreleasepool{        //group_way();        //apply_way();        function_way();    }    return 0;}

代码中采用3中形式的并发:

  1. group_way
  2. apply_way
  3. function_way
    细节可以查看代码。
0 0
原创粉丝点击