GDC dispatch_semaphore

本文介绍了如何在Grand Central Dispatch (GCD)中利用dispatch_semaphore实现并发控制,通过创建、发送信号和等待信号来同步任务和有限资源访问控制。
当我们在处理一系列线程的时候,当数量达到一定量,在以前我们可能会选择使用NSOperationQueue来处理并发控制,但如何在GCD中快速的控制并发呢?答案就是dispatch_semaphore,对经常做unix开发的人来讲,我所介绍的内容可能就显得非常入门级了,信号量在他们的多线程开发中再平常不过了。
  信号量是一个整形值并且具有一个初始计数值,并且支持两个操作:信号通知和等待。当一个信号量被信号通知,其计数会被增加。当一个线程在一个信号量上等待时,线程会被阻塞(如果有必要的话),直至计数器大于零,然后线程会减少这个计数。
  在GCD中有三个函数是semaphore的操作,分别是:
  dispatch_semaphore_create   创建一个semaphore
  dispatch_semaphore_signal   发送一个信号
  dispatch_semaphore_wait    等待信号

  简单的介绍一下这三个函数,第一个函数有一个整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1,根据这样的原理,我们便可以快速的创建一个并发控制来同步任务和有限资源访问控制



  int data = 3;

    __block int mainData = 0;

    __block dispatch_semaphore_t sem = dispatch_semaphore_create(0);

    

    dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL);

    

    dispatch_async(queue, ^(void) {

        int sum = 0;

        for(int i = 0; i < 5; i++)

        {

            sum += data;

            

            NSLog(@" >> Sum: %d", sum);

        }

        

        dispatch_semaphore_signal(sem);

    });

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

    for(int j=0;j<5;j++)

    {

        mainData++;

        NSLog(@">> Main Data: %d",mainData);

    }

    

    

    

    

    dispatch_release(sem);

    dispatch_release(queue);



输出:

2013-07-08 11:33:05.654 dispatch[1102:1e03]  >> Sum: 3

2013-07-08 11:33:05.656 dispatch[1102:1e03]  >> Sum: 6

2013-07-08 11:33:05.657 dispatch[1102:1e03]  >> Sum: 9

2013-07-08 11:33:05.658 dispatch[1102:1e03]  >> Sum: 12

2013-07-08 11:33:05.659 dispatch[1102:1e03]  >> Sum: 15

2013-07-08 11:33:05.660 dispatch[1102:c07] >> Main Data: 1

2013-07-08 11:33:05.660 dispatch[1102:c07] >> Main Data: 2

2013-07-08 11:33:05.660 dispatch[1102:c07] >> Main Data: 3

2013-07-08 11:33:05.661 dispatch[1102:c07] >> Main Data: 4

2013-07-08 11:33:05.661 dispatch[1102:c07] >> Main Data: 5

通过信号量就可以保证,Main Data 永远在Sum之后执行

由于缺乏关于GDC_DMACDA0和GDC_DMACDA1的具体信息,推测它们是直接内存访问控制器(DMAC)的不同通道,以下是GDC_DMACDA0转送后地址与GDC_DMACDA1转送前地址之间可能进行的处理: ### 地址映射与转换 若系统采用了虚拟内存管理,GDC_DMACDA0转送后地址可能是虚拟地址,需要通过内存管理单元(MMU)将其转换为物理地址,再将该物理地址作为GDC_DMACDA1转送前地址。以下是一个简单的伪代码示例说明地址转换过程: ```python # 模拟虚拟地址转物理地址 def virtual_to_physical(virtual_address): # 假设这里有一个映射表 mapping_table = {0x1000: 0x2000} return mapping_table.get(virtual_address, None) # GDC_DMACDA0转送后虚拟地址 gdc_dmacda0_post_transfer_virtual_address = 0x1000 # 转换为物理地址 physical_address = virtual_to_physical(gdc_dmacda0_post_transfer_virtual_address) if physical_address: # 将物理地址作为GDC_DMACDA1转送前地址 gdc_dmacda1_pre_transfer_address = physical_address print(f"GDC_DMACDA1转送前地址: {hex(gdc_dmacda1_pre_transfer_address)}") else: print("地址转换失败") ``` ### 数据预处理 在将GDC_DMACDA0转送后地址的数据用于GDC_DMACDA1转送前地址时,可能需要进行数据预处理。例如,数据格式转换、数据校验、数据加密等。以下是一个简单的数据格式转换示例: ```python # 模拟数据格式转换 def data_format_conversion(data): # 假设将数据的每个字节加1 converted_data = [byte + 1 for byte in data] return converted_data # 假设GDC_DMACDA0转送后的数据 gdc_dmacda0_post_transfer_data = [0x01, 0x02, 0x03] # 进行数据格式转换 converted_data = data_format_conversion(gdc_dmacda0_post_transfer_data) # 将转换后的数据存储到GDC_DMACDA1转送前地址 gdc_dmacda1_pre_transfer_address = 0x2000 # 这里可以实现实际的存储操作,此处仅打印 print(f"转换后的数据: {converted_data} 存储到地址: {hex(gdc_dmacda1_pre_transfer_address)}") ``` ### 同步与协调 为确保GDC_DMACDA0转送完成后GDC_DMACDA1才能开始转送,需要进行同步与协调。可以使用硬件信号(如中断信号)或软件标志位来实现。以下是一个简单的软件标志位同步示例: ```python # 初始化标志位 transfer_complete = False # 模拟GDC_DMACDA0转送完成 def gdc_dmacda0_transfer_complete(): global transfer_complete transfer_complete = True print("GDC_DMACDA0转送完成") # 模拟GDC_DMACDA1等待转送 def gdc_dmacda1_wait_and_transfer(): while not transfer_complete: pass print("GDC_DMACDA1开始转送") # 模拟GDC_DMACDA0转送完成 gdc_dmacda0_transfer_complete() # GDC_DMACDA1开始等待并转送 gdc_dmacda1_wait_and_transfer() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值