我们首先写一个纯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

    细节可以查看代码。

obj-c利用dispatch库并发示例的更多相关文章

  1. Python:利用 selenium 库抓取动态网页示例

    前言 在抓取常规的静态网页时,我们直接请求对应的 url 就可以获取到完整的 HTML 页面,但是对于动态页面,网页显示的内容往往是通过 ajax 动态去生成的,所以如果是用 urllib.reque ...

  2. C/C++ 开源库及示例代码

    C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...

  3. CocoaPods的安装及使用/利用开源库Diplomat实现分享及第三方登录/git的使用

    <<史上最简洁版本>> 1.gem sources -l查看 当前的源 //1.1 sudo -i..以下都是以管理员的身份来操作的 2.gem sources --remov ...

  4. python3:利用smtplib库和smtp.qq.com邮件服务器发送邮件

    python3:利用smtplib库和smtp.qq.com邮件服务器发送邮件 使用qq的邮件服务器需要注意的两个地方主要是: 1.协议问题 使用465端口 SSL 协议 2.口令问题 出现SMTPA ...

  5. 记一次C++编程引用obj文件作为静态库文件

    简介 常用静态库文件的名字一般是 ***.lib ,例如 nisyscfg.lib 就是一个静态库文件,但是一个例程居然是引用 **.obj 文件作为静态库,有点非常规啊. 这是一个NI488.2 的 ...

  6. c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)

    c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...

  7. php学习笔记:利用gd库生成图片,并实现随机验证码

    说明:一些基本的代码我都进行了注释,这里实现的验证码位数.需要用的字符串都可以再设置.有我的注释,大家应该很容易能看得懂. 基本思路: 1.用mt_rand()随机生成数字确定需要获取的字符串,对字符 ...

  8. libJPEG-turbo库使用示例代码

    libJPEG库是用于编码数据为JPEG格式或者解码JPEG格式图片的常用库,OpenCV读取图像底层实现就是利用libJPEG库,而libJPEG-turbo则效率更高. 具体怎么编译编译libJP ...

  9. RAC集群数据库连库代码示例(jdbc thin方式,非oci)

    1.RAC集群数据库连库代码示例(jdbc thin方式,非oci):jdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc ...

随机推荐

  1. shape图形的使用

    shape图形的使用 在项目中如果用到有规律的常规的图形,在能够掌握的前提下建议使用shape图形,shape图形相对与图片来说,占用资源更小,并且使用起来不会失真. 效果图 shape图形1 < ...

  2. K均值聚类的失效性分析

    K均值聚类是一种应用广泛的聚类技术,特别是它不依赖于任何对数据所做的假设,比如说,给定一个数据集合及对应的类数目,就可以运用K均值方法,通过最小化均方误差,来进行聚类分析. 因此,K均值实际上是一个最 ...

  3. How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer

    How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer 1 ...

  4. Linux下yum安装MySQL yum安装MySQL指定版本

    yum安装MySQL 1. 查看有没有安装过     yum list installed MySQL* (有存在要卸载yum remove MySQL*)     rpm -qa | grep my ...

  5. 仿淘宝购物车demo---增加和减少商品数量

    在上一篇博客中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了 ...

  6. C++中友元详解

    问题的提出 我们已知道类具备封装和信息隐 藏的特性.只有类的成员函数才能访问类的私有成员,程式中的其他函数是无法访问私有成员的.非成员函数能够访问类中的公有成员,但是假如将数据成员都定义 为公有的,这 ...

  7. 如何在Cocos2D游戏中实现A*寻路算法(三)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  8. Linux IPC实践(5) --System V消息队列(2)

    消息发送/接收API msgsnd函数 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由ms ...

  9. 【Mac】Mac OS X 安装GNU命令行工具

    macos的很多用户都是做it相关的人,类unix系统带来了很多方面,尤其是经常和linux打交道的人. 但是作为经常使用linux 命令行的人发现macos中的命令行工具很多都是bsd工具,跟lin ...

  10. 手把手教你打造一个心电图效果View Android自定义View

    大家好,看我像不像蘑菇-因为我在学校呆的发霉了. 思而不学则殆 丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力. 好了废话不说 ...