zoukankan      html  css  js  c++  java
  • Semaphore回顾

    用途

    在多线程访问可变变量时,是非线程安全的。可能导致程序崩溃。此时,可以通过使用信号量(semaphore)技术,保证多线程处理某段代码时,后面线程等待前面线程执行,保证了多线程的安全性。使用方法记两个就行了,一个是wait(dispatch_semaphore_wait),一个是signal(dispatch_semaphore_signal)。根据dispatch_semaphore_wait的参数类型提示去创建信号量(dispatch_semaphore_t)即可。
    感觉原理跟PV操作如出一辙。

    不用semaphore时code:

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSLog(@"Hello, World!");
            
            NSMutableArray *lArrM = [NSMutableArray array];
            for (int i = 0; i < 100; ++i) {
                dispatch_async(dispatch_get_global_queue(0, 0), ^{
                    [lArrM addObject:@(i)];
                });
            }
        }
        return 0;
    }
    

    运行结果

     SemephoreTest[3665:130800] Hello, World!
    SemephoreTest(3665,0x700001daa000) malloc: *** error for object 0x10077b2e0: pointer being freed was not allocated
    SemephoreTest(3665,0x700001daa000) malloc: *** set a breakpoint in malloc_error_break to debug
    SemephoreTest(3665,0x700001e2d000) malloc: *** error for object 0x102b00340: pointer being freed was not allocated
    SemephoreTest(3665,0x700001e2d000) malloc: *** set a breakpoint in malloc_error_break to debug
    SemephoreTest[3665:130800] lArrM.count:0
    (lldb) 
    

    用semaphore时code:

    //
    //  ViewController.m
    //  SemophoreTest
    //
    //  Created by LongMa on 2019/8/22.
    //  Copyright © 2019 . All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSMutableArray *lArrM = [NSMutableArray array];
        dispatch_semaphore_t lSema = dispatch_semaphore_create(1);//参数1,代表只能有1个线程同时访问被限制的代码。
        for (int i = 0; i < 1000; ++i) {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                dispatch_semaphore_wait(lSema, DISPATCH_TIME_FOREVER);//wait使信号量的值-1,如果结果为0,其他线程来访问时,需要等待。直到信号量的值大于0
                [lArrM addObject:@(i)];
                NSLog(@"lArrM.count:%zd",lArrM.count);
                dispatch_semaphore_signal(lSema);///wait使信号量的值+1,必须和dispatch_semaphore_wait配对使用。
            });
        }
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"final  delayed lArrM.count:%zd",lArrM.count);
        });
    }
    
    
    @end
    
    
    

    运行结果(用commandlineTool运行代码时,log存在不完整问题):

    ...
     SemophoreTest[9092:877715] lArrM.count:999
     SemophoreTest[9092:877730] lArrM.count:1000
     SemophoreTest[9092:877696] final  delayed lArrM.count:1000
    
    学无止境,快乐编码。 没有一种不经过蔑视、忍受和奋斗就可以征服的命运。
  • 相关阅读:
    【故障处理】ORA-12162: TNS:net service name is incorrectly specified (转)
    android studio 编程中用到的快捷键
    java时间格式串
    android Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
    linux安装vmware
    x1c 2017 安装mint18的坑——grub2
    x1c2017 8G版 win linux的取舍纠结记录
    python的try finally (还真不简单)
    kafka+docker+python
    json文件不能有注释
  • 原文地址:https://www.cnblogs.com/Dast1/p/11392835.html
Copyright © 2011-2022 走看看