我们首先写一个纯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. ERP各个模块的缩写

    财务系统模块: Oracle 总帐管理(GL) Oracle 应付帐管理(AP) Oracle 固定资产管理(FA) Oracle 应收帐管理(AR) Oracle 现金管理(CE) Oracle 项 ...

  2. Oracle 执行计划(Explain Plan) 说明

    如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题. 如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以 ...

  3. Swift的print不换行打印的方法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) swift大多数情况下我们直接用默认的print函数打印就可以 ...

  4. 2.7、Android Studio使用翻译编辑器本地化UI

    如果你的应用支持多语言,你需要合理的管理你的翻译的string资源.Android Studio 提供了翻译编辑器来使查看和管理翻译的资源更加容易. 关于翻译编辑器 翻译后的资源在你的项目里保存在不同 ...

  5. HTML5中 HTML表单和PHP环境搭建及与PHP交互 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 知识点概括:HTML表单/PHP环境搭建/表单提交数据与PHP交互 第一部分:HTML表单 <!DOCTYP ...

  6. Android LK Bootlaoder启动概览

    LK - Little kernel 1. 起源地: bootable\bootloader\lk\arch\arm (1)rule.mk $(BUILDDIR)/trustzone-test-sys ...

  7. RabbitMQ消息队列的小伙伴: ProtoBuf(Google Protocol Buffer)

    什么是ProtoBuf? 一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的语言无关.平台无关.可扩 ...

  8. 用SpriteBuilder简化"耕牛遍地走"的动画效果(二)

    首先使用SpriteBuilder新建一个项目,将之前下载的资源文件夹拖入SpriteBuilder的文件视图. 这里我们只需要一步操作就可以完成原文中在Texture Packer中的那么多操作:即 ...

  9. Torch的安装和学习

    Long long ago, 就已经安装好Torch,这里再记录一下.Torch是Facebook开发的用于AI的科学计算框架,可广泛运用于机器学习的很多算法.相比Caffe,其接口运用更加方便,使用 ...

  10. TCP三次握手及其背后的缺陷

    概述 总结一下TCP中3次握手过程,以及其原生的缺陷 引起的SYN Flood的介绍 [1]TCP三次握手 [2]SYN Flood 1.TCP连接建立--三次握手 几个概念: [1]seq:序号,占 ...