美文网首页
2021-08-04 多线程之多读单写

2021-08-04 多线程之多读单写

作者: 我是小胡胡分胡 | 来源:发表于2021-08-04 15:08 被阅读0次

    如何实现多读单写。
    创建一个自定义并发队列。
    读:同步并发 读
    写:dispatch_barrier_sync 同步栅栏提交到并发队列。AFNetworking设置公共头部header用的此法。
    有很多地方都说可以dispatch_barrier_async并发队列。 实际测试,这种方式会有问题。死锁。 个人理解是队列满了。

    测试程序如下:

    
    #import "testDispatchbarrier.h"
    
    @implementation testDispatchbarrier{
        dispatch_queue_t queue;
        NSInteger aValue;
    }
    
    -(instancetype)init{
        self =[super init];
        //queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        queue = dispatch_queue_create("read_write", DISPATCH_QUEUE_CONCURRENT);
        return self;
    }
    
    
    /// 读者,读者 并发
    /// 读者,写者互斥
    /// 写者,写者互斥
    /// readAvalue,可以在多个线程里面调用
    - (NSInteger)readAvalue {
        __block NSInteger a;
        //同步读取
        dispatch_sync(self->queue, ^{ //用并发队列,可以在多个线程里面调用
            //sleep(5);
            a=self->aValue;
        });//用同步调用,无论是在哪个线程,立刻需要读取到结果,所以用同步提交
        return a;
    }
    
    ///
    ///串行队列
    ///全局并发队列
    ///
    ///
    - (void)write{
          //异步栅栏 调用,设置写
        //下面是AFNetworking的header设置的方法
        dispatch_barrier_sync(self->queue, ^{//写的时候,里面的任务要全部清理完(不管是读还是写,都要等他们执行完),然后只允许我一个人去写
        //dispatch_barrier_async(self->queue, ^{    //如果用dispatch_barrier_async 就会卡死,不能写。 我觉得是因为并发队列满了。
            self->aValue=self->aValue+1;
        }); //用sync等执行完返回,用并发队列,可以多个线程调用
    }
    
    -(void)test{
        testDispatchbarrier *a =[testDispatchbarrier new];
        
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t bingfaqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        for (int i=0; i<1000; i++) {
            dispatch_group_async(group, bingfaqueue, ^{
                NSLog(@"一大堆人读: %@", @([a readAvalue]));
            });
        }
        //1000次+1操作,如果有资源竞争问题,结果值会小于1000
        for (int i=0; i<1000; i++) {
            dispatch_group_async(group, bingfaqueue, ^{
                [a write];
            });
        }
        for (int i=0; i<1000; i++) {
            dispatch_group_async(group, bingfaqueue, ^{
                NSLog(@"一大堆人读: %@", @([a readAvalue]));
            });
        }
    
        //1
        dispatch_group_async(group, bingfaqueue, ^{
             
        });
        
        dispatch_group_async(group, bingfaqueue, ^{
             
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"全部都执行完了=%@",  @([a readAvalue]));
        });
        NSLog(@"开始测试");
    }
    @end
    
    
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        UIButton*btn=[UIButton buttonWithType:UIButtonTypeSystem];
        [self.view addSubview:btn];
        btn.frame=CGRectMake(20, 100, 100, 50);
        btn.backgroundColor=[UIColor redColor];
        [btn setTitle:@"测试" forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside];
    }
    
    -(void)testAction{
        [self test5];
    }
    
    -(void)test5{
        testDispatchbarrier *aa=[testDispatchbarrier new];
        [aa test];
    }
    
    
    @end
    

    相关文章

      网友评论

          本文标题:2021-08-04 多线程之多读单写

          本文链接:https://www.haomeiwen.com/subject/mneuvltx.html