iOS面试题--网络--如何处理多个网络请求的并发的情况
如何处理多个网络请求的并发的情况
一、概念
1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
2.并行 当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
3.区别 并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
举个栗子
1).并发 一个送外卖的A需要把两份外卖分别送到两个客户B和C手里。 A必须先送完B外卖才能接着送C的。这就是并发
2).并行 客户C 分别从饿了么和美团订了一共两份外卖。那么外卖员A和外卖员B需要把外卖一同送到客户C手里。 这就是并行
在iOS中,经常可以看见有这样的需求,就是一个方法要等另外一个方法执行完毕再做相对应的处理,比如说一些网络请求,需要根据上一个请求的返回值做相对应的处理再执行第二个请求,所以我们不能让两个请求同时去请求网络。下面就记录以下通过GCD和NSOperationQueue来控制并发。
二、代码部分(GCD)
GCD
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 创建信号量
__block dispatch_semaphore_t sem = dispatch_semaphore_create();
// 创建队列
dispatch_queue_t queue = dispatch_queue_create("testBlock", NULL);
dispatch_async(queue, ^{
for (int i = ; i<; i++) {
NSLog(@"i的值是:%d",i);
}
// 发送通知
dispatch_semaphore_signal(sem);
});
// 信号量等待
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
for (int j = ; j<; j++) {
NSLog(@"j的值是:%d",j);
}
}
return ;
}
打印结果为
2015-07-28 16:17:04.195 多线程[16370:1833932] i的值是:0
2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:1
2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:2
2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:3
2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:4
2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:5
2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:6
2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:7
2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:8
2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:9
2015-07-28 16:17:04.198 多线程[16370:1833932] j的值是:0
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:1
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:2
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:3
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:4
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:5
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:6
2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:7
2015-07-28 16:17:04.221 多线程[16370:1833932] j的值是:8
2015-07-28 16:17:04.221 多线程[16370:1833932] j的值是:9
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:10
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:11
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:12
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:13
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:14
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:15
2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:16
2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:17
2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:18
2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:19
我们看到先打印完i值后在打印j值 这就完成了并发请求
NSOperationQueue
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// 设置最大线程数
queue.maxConcurrentOperationCount = ;
// 创建一个A操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
for (int i = ; i<; i++) {
NSLog(@"i的值是:%d",i);
}
}];
// 创建一个B操作
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
for (int j = ; j<; j++) {
NSLog(@"j的值是:%d",j);
}
}];
// 分别加入到队列中
[queue addOperation:operationA];
[queue addOperation:operationB];
}
打印结果
2015-07-28 17:51:09.508 111[16598:1880752] j的值是:0
2015-07-28 17:51:09.508 111[16598:1880750] i的值是:0
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:1
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:1
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:2
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:2
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:3
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:3
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:4
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:4
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:5
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:5
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:6
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:6
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:7
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:7
2015-07-28 17:51:09.509 111[16598:1880752] j的值是:8
2015-07-28 17:51:09.509 111[16598:1880750] i的值是:8
2015-07-28 17:51:09.510 111[16598:1880752] j的值是:9
2015-07-28 17:51:09.510 111[16598:1880750] i的值是:9
我们看到打印顺序是交替进行的。 那么如何进行顺序操作呢。只需一行代码。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// 设置最大线程数
queue.maxConcurrentOperationCount = ;
// 创建一个A操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
for (int i = ; i<; i++) {
NSLog(@"i的值是:%d",i);
}
}];
// 创建一个B操作
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
for (int j = ; j<; j++) {
NSLog(@"j的值是:%d",j);
}
}];
// 添加依赖 B要在A打印完在进行打印 所以是B依赖于A 那么只需要添加如下代码即可完成
[operationB addDependency:operationA];
// 分别加入到队列中
[queue addOperation:operationA];
[queue addOperation:operationB];
}
打印结果
2015-07-28 17:54:02.606 111[16625:1882738] i的值是:0
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:1
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:2
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:3
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:4
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:5
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:6
2015-07-28 17:54:02.609 111[16625:1882738] i的值是:7
2015-07-28 17:54:02.610 111[16625:1882738] i的值是:8
2015-07-28 17:54:02.610 111[16625:1882738] i的值是:9
2015-07-28 17:54:02.610 111[16625:1882738] j的值是:0
2015-07-28 17:54:02.610 111[16625:1882738] j的值是:1
2015-07-28 17:54:02.610 111[16625:1882738] j的值是:2
2015-07-28 17:54:02.610 111[16625:1882738] j的值是:3
2015-07-28 17:54:02.610 111[16625:1882738] j的值是:4
2015-07-28 17:54:02.611 111[16625:1882738] j的值是:5
2015-07-28 17:54:02.611 111[16625:1882738] j的值是:6
2015-07-28 17:54:02.611 111[16625:1882738] j的值是:7
2015-07-28 17:54:02.611 111[16625:1882738] j的值是:8
2015-07-28 17:54:02.611 111[16625:1882738] j的值是:9
顺序操作请求完成。
iOS面试题--网络--如何处理多个网络请求的并发的情况的更多相关文章
- iOS 处理多个网络请求的并发的情况
如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...
- iOS面试题01-多线程网络
1.面试题方向: 1>.多线程+网络 2>.项目(简历上的项目,每一个细节:技术实现细节.业务.项目周期.人数) 3>.性能优化:图片优化.内存优化(tableView的循环利用) ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据
网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...
- 【读书笔记】iOS网络-测试与操纵网络流量
一,观测网络流量. 观测网络流量的行为叫做嗅探或数据包分析. 1,嗅探硬件. 从iOS模拟器捕获数据包不需要做特别的硬件或网络配置.如果需要捕获这些数据包,那么可以使用嗅探软件来监听回送设备或是用于连 ...
- iOS中利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G)
前言: 在项目开发当中,往往需要利用网络.而用户的网络环境也需要我们开发者去注意,根据不同的网络状态作相应的优化,以提升用户体验. 但通常我们只会判断用户是在WIFI还是移动数据,而实际上,移动数据也 ...
- iOS开发 - Swift实现检测网络连接状态及网络类型
一.前言 在移动开发中,检测网络的连接状态尤其检测网络的类型尤为重要.本文将介绍在iOS开发中,如何使用Swift检测网络连接状态及网络类型(移动网络.Wifi). 二.如何实现 Reachabili ...
- iOS中利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G) by徐文棋
前言: 在项目开发当中,往往需要利用网络.而用户的网络环境也需要我们开发者去注意,根据不同的网络状态作相应的优化,以提升用户体验. 但通常我们只会判断用户是在WIFI还是移动数据,而实际上,移动数据也 ...
- IOS 网络浅析(一 网络监测~Reachability)
网络监测应用于各种需要连接网络的app设计,由于现在开发的app几乎都用到网络,因此,网络监测也成为了较为重点的知识,下面我给大家简单讲解一下网络监测的实际应用,依旧会有代码哦. 想要实现网络监测,可 ...
- [转载]iOS面试题总
转载自:http://blog.sina.com.cn/s/blog_67eb608b0101r6xb.html (2014-06-13 20:23:33) 转载▼ 标签: 转载 crash 原文 ...
随机推荐
- gcc/g++ 命令的常用选项
gcc/g++ 命令的常用选项使用g++编译CPP文件如果用gcc编译C++源文件时,加以下选项:-lstdc++,否则使用了C++操作的文件编译会出错.假如在程序中用到new delete操作,而不 ...
- 转:【微信小程序】实现锚点定位楼层跳跃的实例
微信小程序实现楼层锚点跳跃,点击不同的锚点进行位置跳跃: 利用:scroll-into-view 来实现: 效果图: wxml: <scroll-view class="cont ...
- C#:xml操作(待补充)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.X ...
- html学习一(html简史及doctype)
html3部分 doctype(html) dtd head body 一.深入浅出HTML与XHTML的区别 HTML(HyperText Markup Language,超文本标记语言)最早的HT ...
- 请介绍WCF服务
WCF本质上提供一个跨进程.跨机器以致跨网络的服务调用 WCF合并了Web服务..net Remoting.消息队列和Enterprise Services的功能并集成在Visual Studio中, ...
- 解决 scrapy 爬虫出现Forbidden by robots.txt
我们在爬取网站的时候,scrapy 默认的是遵循 robots.txt 协议,怎么破解这个文件 操作很简单,找到setting 文件 直接改成
- ansible 提示安装sshpass
之前用ansible一直用的root身份.机器之间又早早的做好了ssh信任.所以一直也没有出现什么问题.今天想想自己不能这么浪了,还是用回普通用户吧: 然而马上就遇到了第一个问题,ansible提示安 ...
- [Informix] unload load
select tabname from systables where tabname like 'aa%' select * from syscolumns where tabname like ...
- C++ 模板详解 肥而不腻
C++模板 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数.返回值取得任意类型. 模板是一种对类型进行参数化的工具: 通常有 ...
- Linux系统CPU频率调整工具使用
现在的CPU耗电很大,按需调节CPU频率对普通桌面及移动设备节能有重要的意义,目前多数Linux发行版都已经默认启用了这个功能,但在一些像数据库,集群系统等特别需要CPU高性能的服务器环境中,Linu ...