多线程

iOS多线程详解
本文详细介绍了iOS开发中的多线程技术,包括线程的基本概念、线程的创建与管理方式、线程间的同步与通信机制等内容。文章还探讨了如何有效利用线程提升应用性能及确保数据安全的方法。

线程是进程中的一条执行路径


开启线程需要占用一定的内存空间,(默认情况下主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。


什么是主线程

一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”

主线程的主要作用

显示刷新/刷新UI界面

处理UI事件(点击事件,滚动事件,拖拽事件)


子线程:后台线程,异步线程


不能把比较耗时的操作放到主线程中。耗时操作会卡住主线程,严重影响UI的流畅度


NSThread

一个NSThread对象就代表一个线程

0、创建线程

NSThread *thread = [[NSThreadalloc]initWithTarget:selfselector:@selector(download)object:nil];


download是一个示例方法。


target

The object to which the message specified by selector is sent.

selector

The selector for the message to send to target. This selector must take only one argument and must not have a return value.

argument

The single argument passed to the target. May be nil.




1、获取主线程与当前线程,判断主线程

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

Returns the NSThread object representing the main thread.


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

Returns the thread object representing the current thread of execution.


NSLog(@"%d",[NSThread isMainThread]);

Returns a Boolean value that indicates whether the current thread is the main thread.

NSLog(@"%d",[thread isMainThread]);

A Boolean value that indicates whether the receiver is the main thread. (read-only)


2、优先级,不常用,了解备用



3、线程的名字

@property (copy) NSString *name

- (void)setName:(NSString *)name;

- (NSString *)name;



更改主线程的名字

NSThread *th = [NSThreadmainThread];

th.name =@"主线程";


Console输出的解释:

2015-08-12 09:32:03.618多线程[8751:2897356] <NSThread: 0x7fbf0a2082a0>{number = 1, name =主线程}


number,线程编号,name ,线程名字,主线程编号永远为1

- (void)setName:(NSString *)name;

- (NSString *)name;


4、创建线程的其他类方法

创建线程后自动启动线程

[NSThreaddetachNewThreadSelector:@selector(download:)toTarget:selfwithObject:@"http://a.jpg"];


隐式创建线程并启动

[selfperformSelectorInBackground:@selector(download:)withObject:nil];

这两种方法的优点,简单快捷,缺点,无法对线程做更详细的设置。



线程的状态

 线程的状态,其实就是以前操作系统课本上提到的,就绪,运行,阻塞三种最简单的状态,前面多加个新建,后面多加个死亡。

1新建:

NSThread *thread = [[NSThreadalloc]initWithTarget:selfselector:@selector(download)object:nil];

2就绪:

[threadstart];




NSLog(@"-----begin");

    

[NSThread sleepForTimeInterval:5];

    

NSLog(@"-----end");




控制线程状态:


线程应该没有死亡,只是不能再start了。


多线程的安全隐患


买票问题演示 核心代码

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


    int count = self.leftTicketCount;


    if (count > 0) {

        

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


        self.leftTicketCount = count -1;


        NSLog(@"%@卖了一张牌,剩余%d张票",[NSThreadcurrentThread].name,self.leftTicketCount);

        

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


    }


解决 :Using the @synchronized Directive   互斥锁


互斥锁使用格式

@synchronized(锁对象){需要锁定的代码}


互斥锁,能防止因多线程抢夺资源造成的数据安全问题,但需要消耗大量的CPU资源


互斥锁的使用前提,多线程抢夺同一块资源,多线程执行同一份代码。


The @synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code. 

you do not have to create the mutex or lock object directly. Instead, you simply use any Objective-C object as a lock token


The object passed to the @synchronized directive is a unique identifier used to distinguish the protected block. 

If you pass the same object in both cases, however, one of the threads would acquire the lock first and the other would block until the first thread completed the critical section.

If you execute the preceding method in two different threads, passing a different object for the anObj parameter on each thread, each would take its lock and continue processing without being blocked by the other. 



线程同步:多条线程在同一条线上执行(按顺序第执行任务)


原子和非原子属性

OC在定义属性时有nonatomic和atomic两种选择

atomic 原子属性,为setter方法加锁(默认是atomic)

nonatomic 非原子属性,不会为setter方法加锁

atomic: 

原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面 默认的就是atomic ,意思就是 setter /getter函数是一个原子操作,如果多线程同时调用setter时,不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter,相当于 函数头尾加了锁 . 这样的话 并发访问性能会比较低 .

原子操作是不可分割的,在执行完毕之前不会被任何其它任务或事件中断。在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。这也是某些CPU指令系统中引入了test_and_set、test_and_clear等指令用于临界资源互斥的原因。但是,在对称多处理器(Symmetric Multi-Processor)结构中就不同了,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。

原子操作,必须完整结束后,再被调用。

nonatomic:

非原子操作 一般不需要多线程支持的时候就用它,这样在 并发访问的时候效率会比较高 . 在objective-c里面通常对象类型都应该声明为非原子性的. iOS中程序启动的时候系统只会自动生成一个单一的主线程.程序在执行的时候一般情况下是在同一个线程里面对一个属性进行操作. 如果在程序中 我们确定某一个属性会在多线程中被使用,并且需要做数据同步,就必须设置成原子性的,但也可以设置成非原子性的,然后自己在程序中用加锁之类的来做数据同步.

iOS开发的建议

所有属性都声明为nonatomic

尽量避免多线程抢夺同一块资源

尽量将加锁,资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力

因为都是nonatomic,刷新UI界面的代码,不要放在子线程中。


线程通信

1、1个线程传递数据给另一个线程

2、在1个线程中执行完特定任务后,转到另一个线程继续执行任务。

3、


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [selfperformSelectorInBackground:@selector(download)withObject:nil];

}



























































【事件触发一致性】研究多智能体网络如何通过分布式事件驱动控制实现有限时间内的共识(Matlab代码实现)内容概要:本文围绕多智能体网络中的事件触发一致性问题,研究如何通过分布式事件驱动控制实现有限时间内的共识,并提供了相应的Matlab代码实现方案。文中探讨了事件触发机制在降低通信负担、提升系统效率方面的优势,重点分析了多智能体系统在有限时间收敛的一致性控制策略,涉及系统模型构建、触发条件设计、稳定性与收敛性分析等核心技术环节。此外,文档还展示了该技术在航空航天、电力系统、机器人协同、无人机编队等多个前沿领域的潜在应用,体现了其跨学科的研究价值和工程实用性。; 适合人群:具备一定控制理论基础和Matlab编程能力的研究生、科研人员及从事自动化、智能系统、多智能体协同控制等相关领域的工程技术人员。; 使用场景及目标:①用于理解和实现多智能体系统在有限时间内达成一致的分布式控制方法;②为事件触发控制、分布式优化、协同控制等课题提供算法设计与仿真验证的技术参考;③支撑科研项目开发、学术论文复现及工程原型系统搭建; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注事件触发条件的设计逻辑与系统收敛性证明之间的关系,同时可延伸至其他应用场景进行二次开发与性能优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值