UI高级------多线程(线程与进程)
2016-08-04 21:32
351 查看
一.线程与进程
进程与线程的理解:- CPU(工厂)—进程(车间)—-线程(工人):如下图
进程与线程的资源共享:
车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征 一个进程的内存空间是共享的,每个线程都可以使用这些共享内存.
加锁机制(控制资源管理):
可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面 有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线 程必须等它结束,才能使用这一块内存
一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人 看到上锁,就在门口排队,等锁打开再进去。这就叫“互斥锁”(Mutual exclusion, 缩写 Mutex),防止多个线程同时读写某一块内存区域.
信号量:
还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出 来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用.
这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥 匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫 做”信号量”(Semaphore),用来保证多个线程不会互相冲突。
不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可 以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独 占的情况下,还是采用这种设计。
操作系统的设计,因此可以归结为三点:
(1)以多进程形式,允许多个任务同时运行;
(2)以多线程形式,允许单个任务分成不同的部分运行;
(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之 间和线程之间共享资源
进程与线程的区别:
进程是指在系统中正在运行的一个应用程序,都有独立的内存空间,一般来说一个应 用程序存在一个进程,但也多个进程的情况
同一个进程中的线程共享内存和资源
二.线程生命周期
CPU的使用权:线程(thread)
- 程序执行的最小单元,按照线性顺序执行的一个流程,CPU的调度单位,一核同时只
能执行一个线程
多线程
一个应用程序有多个线程,多线程不是为了提高运行效率,而是为了提高资源使用效 率来提高系统的效率
一个程序有且只有一个主线程,程序启动时创建(调用main来启动)主线程的生命周 期是和应用程序绑定的,程序退出(结束)时,主线程也就停止了
任何有可能堵塞主线程的任务不要在主线程执行(比如访问网络)
单线程与多线程的执行图:
线程的生命周期:
新建状态(New):新创建了 一个线程对象
就绪状态(Runnable):线 程对象创建后,其他线程调用 了该对象的start()方法,该状 态的线程位于可运行线程池中, 变得可运行,等待获取CPU 的使用权
运行状态(Running):就绪状态的线程获取了CPU ,执行程序代码
阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行 ,直到线程进入就绪状态,才有机会转到运行状态
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
三.线程调度
线程的使用:线程实现
NSTread
优点:NSTread比其他两个轻量级
缺点:需要自己管理线程的生命周期,线程同步,加锁等
Cocoa operation
优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
Cocoa operation相关的类是NSOpration,NSOperationQuque.
NSOperationQuque是操作队列,用来管理和控制NSOpration.NSOpration是操作任务,是抽象类,使用它必须用它的类.
GCD(Grand Central Dispatch)
GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的
一个高效、强大、底层的技术。
线程的使用,代码实现:
NSThread的创建
#import "ViewController.h" #import "CustomThread.h" @interface ViewController () @end @implementation ViewController /* 1 NSThread 常用的类 属性 方法 2 case1~case4 3 退出 取消 */ - (void)viewDidLoad { [super viewDidLoad]; //case1 NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadCallMethod) object:nil]; //启动线程,调用start方法 [thread1 start]; //线程的退出 (只是退出后面还没有来得及执行的线程) // [NSThread exit]; //指定线程退出 //(1)先标记thread1的状态是cancel [self performSelector:@selector(cancelThread1:) withObject:thread1 afterDelay:1]; //case2 (没有返回值 不需要调用start方法) // [NSThread detachNewThreadSelector:@selector(threadCallMethod) toTarget:self withObject:nil]; //case3 // [self performSelectorInBackground:@selector(threadCallMethod) withObject:nil]; // [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>] //case4 自定义线程 // CustomThread *thread4 = [[CustomThread alloc]init]; //启动方法 //直接调用main方法,只是调用了一个普通的方法 // [thread4 main]; //启动线程 新的线程会执行相应线程汇总的main方法,并且会开辟一个新的线程 // [thread4 start]; NSLog(@"ViewController的优先级:%lf",[NSThread threadPriority]); NSLog(@"ViewController是否是主线程:%d",[[NSThread currentThread] isMainThread]); } -(void)cancelThread1:(NSThread*)thread{ [thread cancel]; } -(void)threadCallMethod{ //(2)延迟2s,判断当前线程是否是被取消的状态. [NSThread sleepForTimeInterval:2]; if ([[NSThread currentThread]isCancelled]) { //如果是,退出线程 [NSThread exit]; } NSLog(@"threadPriority的优先级:%lf",[NSThread threadPriority]); NSLog(@"threadCallMethod是否是主线程:%d",[[NSThread currentThread] isMainThread]); } @end
import “CustomThread.h”
@implementation CustomThread-(void)test{
}
-(voi
b5f5
d)main{
NSLog(@"threadPriority的优先级:%lf",[NSThread threadPriority]); NSLog(@"threadCallMethod是否是主线程:%d",[[NSThread currentThread] isMainThread]);
}
NSOperation的创建
import “ViewController.h”
import “CustomOperation.h”
@interface ViewController (){
NSInvocationOperation *cancelOperation;
}
@end
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
//初始化任务队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//设置队列的最大并发数
queue.maxConcurrentOperationCount = 1;
//queue 被挂起(暂停)
queue.suspended = YES;
//添加任务
//case 1
[queue addOperationWithBlock:^{
NSLog(@"operation1"); //队列中的任务是在子线程中执行的.
// NSLog(@”%d”,[[NSThread currentThread]isMainThread]);
}];
//case 2
//NSBlockOperation:能够并发的执行一个或者多个任务
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
for (int i =0; i<10; i++) { NSLog(@"operation2----%d",i); }
}];
//添加任务 和blockOperation的第一任务并发执行
[blockOperation addExecutionBlock:^{
NSLog(@"又执行了一个新的操作:线程:%@",[NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"又执行了一个新的操作:线程:%@",[NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"又执行了一个新的操作:线程:%@",[NSThread currentThread]);
}];
//监听blockOperation中的任务完成后,调用该block
blockOperation.completionBlock=^(){
NSLog(@"blockOperation的任务都完成了");
};
//将operation添加到queue
[queue addOperation:blockOperation];
//case 3
NSInvocationOperation *invocationOp =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadCallMethod) object:nil];
[queue addOperation:invocationOp];
//case 4 自定义operation
CustomOperation *cusOp = [[CustomOperation alloc]init];
//设置当前opration在queue中的优先级,优先级越大,越先执行.
[cusOp setQueuePriority:NSOperationQueuePriorityVeryHigh];
//addDependency:添加依赖关系(改变执行的顺序)
//blockOperation依赖于invocationOp
//必须等到invocationOp执行完毕后才可以执行blockOperation
[blockOperation addDependency:invocationOp];
[queue addOperation:cusOp];
//取消任务
cancelOperation = [[NSInvocationOperation alloc]initWithTarget:self selector: @selector(cancelOperationTask) object:nil];
[queue addOperation:cancelOperation];
//取消单个任务
//(1)先将operation标记成cancel状态
//(2)在任务执行的时候判断是否是cancel状态
// [self performSelector:@selector(cancelSingelOperation:) withObject:cancelOperation afterDelay:1];
//取消所有任务 [self performSelector:@selector(cancelallOperation:) withObject:queue afterDelay:1]; //关闭暂停 queue.suspended = NO;
}
-(void)cancelallOperation:(NSOperationQueue*)q{
//如果一个操作已经在执行,不会停止. //队列取消所有的任务 [q cancelAllOperations];
}
-(void)cancelSingelOperation:(NSInvocationOperation*)op{
[op cancel];
}
-(void)cancelOperationTask{
[NSThread sleepForTimeInterval:2]; if (cancelOperation.isCancelled) { NSLog(@"cancelOperation is cancelled"); }else{ NSLog(@"cancelOperation is executing"); }
}
-(void)threadCallMethod{
for (int i =0; i<10; i++) { NSLog(@"operation3----%d",i); }
}
@end
import “CustomOperation.h”
@implementation CustomOperation-(void)main{
for (int i =0; i<10; i++) { NSLog(@"operation4----%d",i); }
}
@end
“`
四 .同步,异步,阻塞,非阻塞
名词解释:- 队列:是先进先出(FIFO, First-In-First-Out)的线性表。通常用链表或者数组来实 现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作
任务:具体要做的东西,比如方法调用等
串行 xing(serial):使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度,指我们做任务时,一个一个步骤去执行
并发(Concurrent):一个处理器同时处理多个任务。并发事件之间不一定要同一 时刻发生,指逻辑上的同时发生
并行( parallel):多个处理器或多核处理器同时处理多个不同的任务。同时发生的 两个并发事件,具有并发的含义,而并发则不一定并行,指物理上的同时发生。
同步:调用者调用一个任务开始执行后,调用者得等待 拿到了结果 才会继续往下执 行
异步:调用者调用一个任务开始执行后,调用者不用等待 拿到结果,会继续往下执行。 实际上任务执行完成后会通知调用者
阻塞:指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回
非阻塞:指不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回
死锁:是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而 造成的一种阻塞的现象
互斥锁:多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读 写的机制
信号量:又称为信号灯,是一个计数器,它用来记录对某个资源(如共享内存)的存 取状况
相关文章推荐
- posix多线程有感--线程高级编程(进程的优先级)
- UI-进程与线程(多线程、主次线程)
- posix多线程有感--线程高级编程(进程的优先级)
- posix多线程有感--线程高级编程(进程的优先级)
- 多线程之进程、线程与多线程文字滚动的实现
- Java程序、进程和线程-Java对多线程的支持-Java线程的同步--2011年09月05日
- 【日积月累】关于进程 线程和一些常见的多线程概念
- Java 多线程编程之一 进程与线程,并发和并行的区别:吃馒头的比喻
- java 孙鑫 第五课 Java 的多线程,程序、进程和线程的概念
- .NET Framework 2.0高级编程学习笔记(三):进程与线程
- 关于进程、线程和Android的单线程模型UI
- java高级多线程编程--关于线程的停止问题
- 进程,线程,多进程,多线程以及主线程
- java学习5---Java 的多线程,程序、进程和线程的概念
- Java第七课 Java的多线程程序进程和线程的概念,实现多线程的两种方式,线程同步的原理,线程的死锁,运用wait和notify来实现producer - consumer关系,线程终止的两种情况。
- 进程和线程有什么区别?什么是多线程?
- 进程,线程,多线程概念
- java高级多线程编程--关于线程的停止问题
- 关于进程、线程、单例和android的单线程模型UI
- Android多线程系统概述(sundy深入浅出)之进程和线程