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 原文 ...
随机推荐
- 【Android UI设计与开发】使用ViewPager实现欢迎引导页面
一.实现的效果图 每次看别人的代码前,必需要先看实现的效果图达到了一个什么样的效果,是不是跟自己想要实现的效果类似.有图才有真相嘛,同一时候,最下方有源代码的下载地址,差点儿源代码的每一行都有凝视,写 ...
- mysql date and time type ---- mysql 时间&日期 类型详解
mysql 中支持用多种方式来表示时间与日期 一.mysql 中能表示时间与日期的数据类型: 1.表示年 ) -- 最好不要用这个数据类型.对于年份的取值中有[1901 --> 2155] + ...
- Jquery.Treeview+Jquery UI制作Web文件预览
效果图: 前台Html: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="D ...
- Ubuntu 16.04下搭建kubernetes集群环境
简介 目前Kubernetes为Ubuntu提供的kube-up脚本,不支持15.10以及16.04这两个使用systemd作为init系统的版本. 这里详细介绍一下如何以非Docker方式在Ubun ...
- Node.js开发入门—使用cookie保持登录
这次来做一个站点登录的小样例,后面会用到. 这个演示样例会用到Cookie.HTML表单.POST数据体(body)解析. 第一个版本号,我们的用户数据就写死在js文件中. 第二个版本号会引入Mong ...
- Atitit.各种 数据类型 ( 树形结构,表形数据 ) 的结构与存储数据库 attilax 总结
Atitit.各种 数据类型 ( 树形结构,表形数据 ) 的结构与存储数据库 attilax 总结 1. 数据结构( 树形结构,表形数据,对象结构 ) 1 2. 编程语言中对应的数据结构 jav ...
- 【Android】14.0 第14章 内部存储与外部SD卡存储—本章示例主界面
分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 Android使用的文件系统是基于Linux的文件系统,在Android应用程序中,开发人员既可以建立和访问程序自 ...
- Cocoa、Foundation、UIKit、Objective-c、XCode、Interface Builder的概念
转自:http://blog.csdn.net/hou_cocoa/article/details/6187418 Cocoa 是在Mac OS X系统上原生的一个编译环境.他包含两个框架,其实就是一 ...
- 使用 nice、cpulimit 和 cgroups 限制 cpu 占用率
Linux内核是一名了不起的马戏表演者,它在进程和系统资源间小心地玩着杂耍,并保持系统的能够正常运转. 同时,内核也很公正:它将资源公平地分配给各个进程. 但是,如果你需要给一个重要进程提高优先级时, ...
- pycharm设置安装python第三方插件
pycharm设置安装python第三方插件 转载于:https://www.mindg.cn/?p=80 今天下了一个pycharm,设置用它来安装python插件,以下是安装步骤,与大家分享,我的 ...