多线程01 pthread NSThread 多线程的资源共享问题-锁

凡是跟UI相关的都是在主线程执行的

UIKit类库的线程都是不安全的 所以我们需要在主线程上更新UI 因此主线程又叫UI线程

多线程的核心思想 : 就是把耗时操作放在后台执行,避免耗时操作卡死UI

currentThread : 查看当前线程

NSLog(@"%@",[NSThread currentThread]);

同步和异步

同步和异步是任务 / 代码 执行的两种方式

同步--->多个任务按顺序依次执行,就是同步执行

异步--->多个任务同时执行,就是异步执行

pthread

参数1 : 子线程的ID / 标识

在C语言中,一般带`_t` / `_ref`标识数据类型

参数2 : 子线程的属性,一般传NULL

NULL : 表示空地址,一般在C语言使用;

nil : 表示空对象,一般在OC使用;

其实,NULLh和nil本质上没有半点儿区别

参数3 : 子线程需要执行的函数

void *(*)(void *) : 表示指向函数的指针,即函数名;函数名就是表示函数地址;

数组地址就是数组名或者数组第0个角标元素的地址

void * 表示可以指向任何地址的指针,代表任意数据类型;类似于OC的id;

返回值    函数名    函数参数

void *    (*)    (void *)

参数4 : 传入到子线程需要执行的函数的参数

返回值 : int;在很多C语言框架中,并不是遵守非零既真;因为成功的结果只有一个,0是唯一的;失败的原因有很多;

线程调试 : 查看方法执行的线程是否是主线程或者子线程

{number = 1, name = main} : 表示主线程

{number = 3, name = (null)} : 只要number != 1 就表示子线程

提示 : 千万不要纠结number到底等于几,系统分配的

// 参数1

pthread_t ID;

// 创建了一个子线程,执行demo函数

int result = pthread_create(&ID, NULL, demo, NULL);

// 判断创建子线程是否成功

if (result == 0) {

NSLog(@"创建子线程成功");

} else {

NSLog(@"创建子线程失败");

}

子线程执行的函数

*/

void *demo(void *param)

{

NSString *str = (__bridge NSString *)(param);

// currentThread : 查看当前线程

NSLog(@"demo %@ - %@",[NSThread currentThread],str);

return NULL;

}


NSThread创建线程三种方式


[self performSelectorInBackground:@selector(demo:) withObject:@"perform"];

以上参数介绍:

1.NSObject分类方法创建子线程

2.不可以拿到线程对象

3.不需要手动启动线程


[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"detach"];

以上参数介绍:

1.类方法创建子线程

2.不可以拿到线程对象

3.不需要手动启动线程


// 创建线程对象

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:@"alloc"];

// 启动线程

[thread start];

以上参数介绍:

1.构造方法创建子线程

2.可以拿到线程对象

3.需要手动启动线程


通知主线程刷新UI

// waitUntilDone : 是否等待updateUI执行完,再执行后面的代码,一般传入NO

[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];


关于以上使用调用方法中-target和selector关系

@selector中需要传入一个方法

而target中需要传入对象告诉系统 这个方法是哪个对象的


线程的声明周期

提示 : 程序员只能做新建和就绪,其他的都由系统来处理

// 创建线程对象 : 新建状态

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];

// 启动线程 : 就绪状态(把线程对象添加到可调度线程池,等待被CPU调度执行)

[thread start];

// sleepForTimeInterval : 使当前线程休眠到指定时长

[NSThread sleepForTimeInterval:1.0];

// sleepUntilDate : 使当前线程休眠到指定日期

[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];

// 使当前线程强制死亡

[NSThread exit];


线程的属性

//新建状态

NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];

// 设置线程对象的name属性 : 标识一个唯一的线程对象,方便跟踪

thread1.name = @"t1";

thread1.threadPriority = 1.0;

// 设置线程对象的优先级 : 浮点数;范围是0.0~1.0;最高是1.0;默认是0.5

// 线程优先级不能决定线程执行的先后顺序,只能决定某个线程有更多的机会被CPU先调度执行完,概率事件

// 注意 : 实际开发中,千万不要设置优先级或者服务器质量,会出现意想不到的问题;使用默认的,让系统自己来处理

// threadPriority : 在目前即将被废弃,使用qualityOfService来替代;

thread1.qualityOfService = NSQualityOfServiceUserInteractive;

// stackSize : 线程占用内存空间大小

NSLog(@"子 %tu",[NSThread currentThread].stackSize / 1024);


多线程的资源共享问题

// 互斥锁 / 同步锁 : 使用了线程同步技术

// 特点 : 可以保证被锁定的代码,同一时间只有一个线程可以访问

// self : 表示互斥锁的参数;互斥锁的参数,又叫做锁对象;

// 锁对象 : 任何继承自NSObject的对象,都可以作为互斥锁的参数;内部有把锁,默认是开启的

// 锁对象必须是全局的对象;self是最方便获取的全局的锁对象

// 局部锁对象是锁不住的,因为每次线程进来之前会新建一把锁

// 提示 : 加锁的事情,不是再客户端操作的;是服务器加锁的,多线程资源共享绝大多数是在服务器发生;

// 提示 : 加锁是牺牲了性能,保证安全.客户端的性能不能轻易牺牲

@synchronized (self)

{

      //需要被锁定的代码

}

参数必须传全局对象 多数传self 


原子属性

使用nonatomic修饰的属性为非原子属性

使用atomic修饰的属性为原子属性

原子属性 : 单写多读

单写多读 : 同一时间只有一个线程可以访问setter方法;但是可以有多个线程访问getter方法

注意 : 原子属性的setter方法是线程安全的,getter方法是线程非安全的

setter方法内部有把自旋锁


自旋锁 :

 看不见的,由系统封装的

可以保证被锁定的代码,同一时间只能有一个线程可以访问

一旦外面的线程,发现代码被自旋锁锁定,外面的线程会以死循环的方式等待开锁

互斥锁 :

可以保证被锁定的代码,同一时间只能有一个线程可以访问

一旦外面的线程,发现代码被互斥锁锁定,外面的线程会进入就绪状态,等待开锁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一、多线程基础 基本概念 进程进程是指在系统中正在运行的一个应用程序每个进程之间是独立的,每个进程均运行在其专用且...
    AlanGe阅读 542评论 0 0
  • 多线程基本概念 单核CPU,同一时间cpu只能处理1个线程,只有1个线程在执行 。多线程同时执行:是CPU快速的在...
    WeiHing阅读 697评论 1 5
  • 一个人的所有问题,都存在于他的身体里面,他的基本问题,就是他害怕自己“复活”,体验到丰富的情绪。 我们不得不面对一...
    明莹阅读 261评论 0 0
  • 你的眼睛透着一幅画, 特别、神秘、深邃 时而蜷缩在椅子上, 引着鼻烟,恍若时人 时而...
    呆兜阅读 211评论 0 3
  • 作为一个90后,星爷的黄金时代似乎离我,我们很远,只是浅浅记得小时电影频道一遍遍重播的怀旧电影《功夫之王》,却...
    Secretes阅读 207评论 0 2