zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

obj-c利用dispatch库并发示例

并发 利用 示例 OBJ Dispatch
2023-09-14 08:56:51 时间
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 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中形式的并发:


Dispatch Source 应用 Dispatch Source 源是一个偏底层的函数集合,使用时CPU负荷非常小,尽量不占资源,开发过程中大多是配合定时器使用。
patch,是打补丁的命令,有很多用法,见帮助#man patch patch -p0  ( p 指的是路径,后面的数字表示去掉路径的第几部分。 0 ,表示不去掉,为全路径) patch -p1  ( p 后面的数字 1 ,表示去掉前第一个路径) fetch http://people.