cf是单线程和多线程的区别任务还是多线程任务?

查看: 5634|回复: 67
CF线程过你想过的代码(更新线程即可)有图有真相
阅读权限20
在线时间7 小时
积分主题听众
已帮网友解决0 个问题
如果您下载的软件是收费的"请千万不要付款",那绝对是骗子,请立即联系本站举报,若您执意要付款被骗后本站概不负责。 CF一键结束线程,只需将你
24.png (85.96 KB, 下载次数: 0)
00:01 上传
的线程更改到源码,编译即可....
仅供新手研究,大手勿喷~
联系我时,请说是在 挂海论坛 上看到的,谢谢!
23:59 上传
点击文件名下载附件
下载积分: 海币 -2
107.95 KB, 下载次数: 276, 下载积分: 海币 -2
售价: 2 海币 &[]
结束cf指定线程
00:00 上传
点击文件名下载附件
下载积分: 海币 -2
308.4 KB, 下载次数: 63, 下载积分: 海币 -2
引用的模块
上一篇:下一篇:
阅读权限10
在线时间24 小时
积分主题听众
已帮网友解决0 个问题
我告诉自己这个帖子是一定要回的!这是百年难得一见的好贴啊!
阅读权限10
在线时间24 小时
积分主题听众
已帮网友解决0 个问题
楼主我只想问你检测线程怎么找
阅读权限10
在线时间1 小时
积分主题听众
已帮网友解决0 个问题
我告诉自己这个帖子是一定要回的!这是百年难得一见的好贴啊!
阅读权限10
在线时间1 小时
积分主题听众
已帮网友解决0 个问题
呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜
阅读权限10
在线时间9 小时
积分主题听众
已帮网友解决0 个问题
我告诉自己这个帖子是一定要回的!这是百年难得一见的好贴啊!
阅读权限20
在线时间7 小时
积分主题听众
已帮网友解决0 个问题
楼主我只想问你检测线程怎么找
找crossfire.exe模块里面的线程
阅读权限20
在线时间26 小时
积分主题听众
已帮网友解决0 个问题
逗比 你确定能结束掉?
阅读权限10
在线时间5 小时
积分主题听众
已帮网友解决0 个问题
我告诉自己这个帖子是一定要回的!这是百年难得一见的好贴啊!
阅读权限10
在线时间15 小时
积分主题听众
已帮网友解决0 个问题
希望外挂海论坛越办越好!
Powered by Discuz! X3.2
Comsenz Inc.多线程基本概念
进程是指在系统中正在运行的一个应用程序。每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。
2-1 基本概念
1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程),线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行。
2-2 线程的串行
1个线程中任务的执行是串行的,如果要在1个线程中执行多个任务,那么只能一个一个地按顺序执行这些任务。也就是说,在同一时间内,1个线程只能执行1个任务。
3-1 基本概念
即1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务。
3-2 线程的并行
并行即同时执行。比如同时开启3条线程分别下载3个文件(分别是文件A、文件B、文件C。
3-3 多线程并发执行的原理
在同一时间里,CPU只能处理1条线程,只有1条线程在工作(执行)。多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换),如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象
3-4 多线程优缺点
1)能适当提高程序的执行效率。
2)能适当提高资源利用率(CPU、内存利用率)
1)开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。
2)线程越多,CPU在调度线程上的开销就越大。
3)程序设计更加复杂:比如线程之间的通信、多线程的数据共享
04 多线程在iOS开发中的应用
4-1 主线程
1)一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”。
2)作用。刷新显示UI,处理UI事件。
4-2 使用注意
1)不要将耗时操作放到主线程中去处理,会卡住线程。
2)和UI相关的刷新操作必须放到主线程中进行处理。
多线程实现方案
//pthread需要包含头文件
//1.创建线程对象
NSString *name = @&线程&;
//2.使用pthread创建线程
//第一个参数:线程对象地址
//第二个参数:线程属性
//第三个参数:指向函数的指针
//第四个参数:传递给该函数的参数
pthread_create(&thread, NULL, run, (__bridge void *)(name));
2.NSThread
(1)基本使用
**第一种:alloc init**
需要手动开启线程,可以拿到线程对象进行详细设置
//1.创建线程
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@&线程&];
//2.启动线程
[thread start];
**第二种:分离(detach)出一条子线程**
自动启动线程,无法对线程进行更详细的设置
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@&分离出的子线程&];
**第三种:后台线程**
自启动,不能详细设置
[self performSelectorInBackground:@selector(run:) withObject:@&后台线程&];
(2)设置线程属性
//线程名称
thread.name = @&线程A&;
//线程的优先级,取值范围0.0~1.0,1.0的优先级最高,默认0.5
thread.threadPriority = 1.0;
(3)线程的状态
//线程的各种状态:新建-就绪-运行-阻塞-死亡
//常用的控制线程状态的方法
[NSThread exit];//退出当前线程
[NSThread sleepForTimeInterval:2.0];//阻塞线程
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];//阻塞线程
//注意:线程死了不能复生
(4)线程安全
01 前提:多个线程访问同一块资源会发生数据安全问题
02 解决方案:加互斥锁
03 相关代码:@synchronized(self){}
04 专业术语-线程同步
05 原子和非原子属性(是否对setter方法加锁)
(5)线程间通信
-(void)touchesBegan:(nonnull NSSet&UITouch *& *)touches withEvent:(nullable UIEvent *)event
//开启子线程下载图片
[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
-(void)downloadImage
//1.确定图片url
NSURL *url = [NSURL URLWithString:@&http://p6.qhimg.com/t01d1ab.jpg&];
//2.根据url地址下载图片数据到本地(二进制数据)
NSData *data = [NSData dataWithContentsOfURL:url];
//3.把下载到本地的二进制数据转换成图片
UIImage *image = [UIImage imageWithData:data];
//4.回到主线程刷新UI
//4.1 第一种方式
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
//4.2 第二种方式
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
//4.3 第三种方式
[self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
(6)如何计算代码段的执行时间
//第一种方法
NSDate *start = [NSDate date];
//2.根据url地址下载图片数据到本地(二进制数据)
NSData *data = [NSData dataWithContentsOfURL:url];
NSDate *end = [NSDate date];
NSLog(@&第二步操作花费的时间为%f&,[end timeIntervalSinceDate:start]);
//第二种方法
CFTimeInterval start = CFAbsoluteTimeGetCurrent();
NSData *data = [NSData dataWithContentsOfURL:url];
CFTimeInterval end = CFAbsoluteTimeGetCurrent();
NSLog(@&第二步操作花费的时间为%f&,end - start);
(1)GCD基本知识
两个核心概念 队列和任务
同步函数和异步函数
(2)GCD基本使用【重点】
(3)GCD线程间通信
//0.获取一个全局的队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//1.先开启一个线程,把下载图片的操作放在子线程中处理
dispatch_async(queue, ^{
//2.下载图片
NSURL *url = [NSURL URLWithString:@&http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f0b14bbf9a185.jpg&];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
NSLog(@&下载操作所在的线程--%@&,[NSThread currentThread]);
//3.回到主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image =
//打印查看当前线程
NSLog(@&刷新UI---%@&,[NSThread currentThread]);
(4)GCD其它常用函数
01 栅栏函数(控制任务的执行顺序)
dispatch_barrier_async(queue, ^{
NSLog(@&--dispatch_barrier_async-&);
02 延迟执行(延迟?控制在哪个线程执行)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@&---%@&,[NSThread currentThread]);
03 一次性代码(注意不能放到懒加载)
-(void)once
//整个程序运行过程中只会执行一次
//onceToken用来记录该部分的代码是否被执行过
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
NSLog(@&-----&);
04 快速迭代(开多个线程并发完成迭代操作)
dispatch_apply(subpaths.count, queue, ^(size_t index) {
05 队列组(同栅栏函数)
//创建队列组
dispatch_group_t group = dispatch_group_create();
//队列组中的任务执行完毕之后,执行该函数
dispatch_group_notify(dispatch_group_t group,
dispatch_queue_t queue,
dispatch_block_t block);
4.NSOperation
NSOperation是对GCD的包装
两个核心概念【队列+操作】
NSOperation本身是抽象类,只能只有它的子类
三个子类分别是:NSBlockOperation、NSInvocationOperation以及自定义继承自NSOperation的类
NSOperation和NSOperationQueue结合使用实现多线程并发
// 1.NSInvocationOperation
//1.封装操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
//2.启动操作
[operation start];
-------------------------------------------------
// 2.NSBlockOperation
//1.封装操作
NSBlockOperation提供了一个类方法,在该类方法中封装操作
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//在主线程中执行
NSLog(@&---download1--%@&,[NSThread currentThread]);
//2.追加操作,追加的操作在子线程中执行
[operation addExecutionBlock:^{
NSLog(@&---download2--%@&,[NSThread currentThread]);
[operation addExecutionBlock:^{
NSLog(@&---download3--%@&,[NSThread currentThread]);
//3.启动执行操作
[operation start];
----------------------------------------------
// 3.自定义NSOperation
//如何封装操作?
//自定义的NSOperation,通过重写内部的main方法实现封装操作
-(void)main
NSLog(@&--main--%@&,[NSThread currentThread]);
//如何使用?
//1.实例化一个自定义操作对象
ZCOperation *op = [[ZCOperation alloc]init];
//2.执行操作
[op start];
NSOperationQueue
(1)NSOperation中的两种队列
主队列 通过mainQueue获得,凡是放到主队列中的任务都将在主线程执行
非主队列 直接alloc init出来的队列。非主队列同时具备了并发和串行的功能,通过设置最大并发数属性来控制任务是并发执行还是串行执行
//自定义NSOperation
-(void)customOperation
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封装操作
//好处:1.信息隐蔽
//2.代码复用
ZCOperation *op1 = [[ZCOperation alloc]init];
ZCOperation *op2 = [[ZCOperation alloc]init];
//3.添加操作到队列中
[queue addOperation:op1];
[queue addOperation:op2];
//NSBlockOperation
- (void)block
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封装操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@&1----%@&,[NSThread currentThread]);
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@&2----%@&,[NSThread currentThread]);
[op2 addExecutionBlock:^{
NSLog(@&3----%@&,[NSThread currentThread]);
[op2 addExecutionBlock:^{
NSLog(@&4----%@&,[NSThread currentThread]);
//3.添加操作到队列中
[queue addOperation:op1];
[queue addOperation:op2];
//补充:简便方法
[queue addOperationWithBlock:^{
NSLog(@&5----%@&,[NSThread currentThread]);
//NSInvocationOperation
- (void)invocation
GCD中的队列:
串行队列:自己创建的,主队列
并发队列:自己创建的,全局并发队列
NSOperationQueue
主队列:[NSOperationQueue mainqueue];凡事放在主队列中的操作都在主线程中执行
非主队列:[[NSOperationQueue alloc]init],并发和串行,默认是并发执行的
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封装操作
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download2) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download3) object:nil];
//3.把封装好的操作添加到队列中
[queue addOperation:op1];//[op1 start]
[queue addOperation:op2];
[queue addOperation:op3];
(3)NSOperation其它用法
设置最大并发数【控制任务并发和串行】
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.设置最大并发数
//注意点:该属性需要在任务添加到队列中之前进行设置
//该属性控制队列是串行执行还是并发执行
//如果最大并发数等于1,那么该队列是串行的,如果大于1那么是并行的
//系统的最大并发数有个默认的值,为-1,如果该属性设置为0,那么不会执行任何任务
queue.maxConcurrentOperationCount = 2;
暂停和恢复以及取消
//设置暂停和恢复
//suspended设置为YES表示暂停,suspended设置为NO表示恢复
//暂停表示不继续执行队列中的下一个任务,暂停操作是可以恢复的
if (self.queue.isSuspended) {
self.queue.suspended = NO;
self.queue.suspended = YES;
//取消队列里面的所有操作
//取消之后,当前正在执行的操作的下一个操作将不再执行,而且永远都不在执行,就像后面的所有任务都从队列里面移除了一样
//取消操作是不可以恢复的
[self.queue cancelAllOperations];
---------自定义NSOperation取消操作--------------------------
-(void)main
//耗时操作1
for (int i = 0; i&1000; i++) {
NSLog(@&任务1-%d--%@&,i,[NSThread currentThread]);
NSLog(@&+++++++++++++++++++++++++++++++++&);
//苹果官方建议,每当执行完一次耗时操作之后,就查看一下当前队列是否为取消状态,如果是,那么就直接退出
//好处是可以提高程序的性能
if (self.isCancelled) {
//耗时操作2
for (int i = 0; i&1000; i++) {
NSLog(@&任务1-%d--%@&,i,[NSThread currentThread]);
NSLog(@&+++++++++++++++++++++++++++++++++&);
(3)NSOperation实现线程间通信
开子线程下载图片
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.使用简便方法封装操作并添加到队列中
[queue addOperationWithBlock:^{
//3.在该block中下载图片
NSURL *url = [NSURL URLWithString:@&http://news.51sheyuan.com/uploads/allimg/442IB-2.jpg&];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
NSLog(@&下载图片操作--%@&,[NSThread currentThread]);
//4.回到主线程刷新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image =
NSLog(@&刷新UI操作---%@&,[NSThread currentThread]);
下载多张图片合成综合案例(设置操作依赖)
//02 综合案例
- (void)download2
NSLog(@&----&);
//1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封装操作下载图片1
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@&http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f0b14bbf9a185.jpg&];
NSData *data = [NSData dataWithContentsOfURL:url];
//拿到图片数据
self.image1 = [UIImage imageWithData:data];
//3.封装操作下载图片2
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@&http://pic.58pic.com/58pic/13/87/82/27Q58PICYje_1024.jpg&];
NSData *data = [NSData dataWithContentsOfURL:url];
//拿到图片数据
self.image2 = [UIImage imageWithData:data];
//4.合成图片
NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{
//4.1 开启图形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
//4.2 画image1
[self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
//4.3 画image2
[self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
//4.4 根据图形上下文拿到图片数据
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
NSLog(@&%@&,image);
//4.5 关闭图形上下文
UIGraphicsEndImageContext();
//7.回到主线程刷新UI
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imageView.image =
NSLog(@&刷新UI---%@&,[NSThread currentThread]);
//5.设置操作依赖
[combine addDependency:op1];
[combine addDependency:op2];
//6.添加操作到队列中执行
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:combine];
使用create函数创建的并发队列和全局并发队列的主要区别:
1.全局并发队列在整个应用程序中本身是默认存在的,并且对应有高优先级、默认优先级、低优先级和后台优先级一共四个并发队列,我们只是选择其中的一个直接拿来用。而create函数是实打实的从头开始去创建一个队列。
2.在iOS6.0之前,在GCD中凡是使用了带create和retain的函数在最后都需要做一次release操作。而主队列和全局并发队列不需要我们手动release。当然了,在iOS6.0之后GCD已经被纳入到了ARC的内存管理范畴中,即便是使用retain或者create函数创建的对象也不再需要开发人员手动释放,我们像对待普通OC对象一样对待GCD就OK。
3.在使用栅栏函数的时候,苹果官方明确规定栅栏函数只有在和使用create函数自己的创建的并发队列一起使用的时候才有效(没有给出具体原因)
4.其它区别涉及到XNU内核的系统级线程编程,不一一列举。
5.给出一些参考资料(可以自行研究):
GCDAPI:https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html#//apple_ref/c/func/dispatch_queue_create
Libdispatch版本源码:http://www.opensource.apple.com/source/libdispatch/libdispatch-187.5/
阅读(...) 评论()

参考资料

 

随机推荐