ToB企服应用市场:ToB评测及商务社交产业平台
标题:
iOS 锁总结(cc)
[打印本页]
作者:
飞不高
时间:
2024-7-16 13:53
标题:
iOS 锁总结(cc)
iOS中atomic和synchrosize锁的本质是什么?
在iOS中,atomic和@synchronized锁的本质涉及底层的多线程同步机制。以下是关于这两者本质的详细解释:
atomic
界说与用途
:
atomic是Objective-C属性修饰符的一种,用于指示属性的存取方法是线程安全的。
当一个属性被声明为atomic时,编译器会生成线程安全的存取方法,以确保在多线程环境下该属性的访问不会导致数据竞争。
实现机制
:
在Objective-C的运行时实现中(比方在objc4的实现里),atomic是通过自旋锁(spinlock_t)来实现的。
当一个线程实验获取或设置atomic属性时,它会先获取自旋锁,执行操作后开释锁。这确保了同一时间只有一个线程能够访问该属性。
性能与限定
:
固然atomic能提供线程安全性,但它并不保证复合操作的原子性。比方,先检查后执行(check-then-act)的操作仍旧大概不安全。
atomic属性的存取操作相对于nonatomic会有更高的性能开销,由于涉及到锁的获取和开释。
@synchronized
界说与用途
:
@synchronized是Objective-C中的一个指令,用于创建一个互斥锁(mutex)来掩护特定代码段的执行,防止多个线程同时执行该段代码。
它用于确保一段代码在同一时间只能被一个线程执行,从而避免数据竞争和条件竞争。
实现机制
:
@synchronized指令内部使用了一个互斥锁(mutex)来实现同步。
当线程进入@synchronized代码块时,会实验获取锁。如果锁已经被其他线程持有,则当火线程会壅闭,直到锁被开释。
一旦线程获取了锁,它就可以安全地执行@synchronized代码块中的代码。执行完毕后,锁会被主动开释。
性能与限定
:
使用@synchronized可以确保线程安全,但也会引入肯定的性能开销,特殊是在高并发场景下。
与atomic不同,@synchronized可以用于掩护更复杂的操作或代码段,而不但仅是单个属性的存取。
总的来说,atomic和@synchronized在iOS中都是用于实现线程同步的机制,但它们的用途和实现方式有所不同。atomic重要用于掩护属性的线程安全存取,而@synchronized则用于掩护更广泛的代码段免受并发访问的影响。
扩展:
iOS中atomic属性的作用是什么?
synchronized锁的使用场景有哪些?
atomic和synchronized有何不同?
自旋锁
iOS中自己怎么实现一个自旋锁?
在iOS中,你可以使用OSSpinLock来实现自旋锁,但必要留意的是,从iOS 10和macOS 10.12开始,Apple已经弃用了OSSpinLock,由于它大概在高并发情况下导致优先级反转和其他问题。尽管如此,为相识释概念,我会起首展示一个基于OSSpinLock的简单示例,然后提供一个使用pthread_spinlock_t的替代方案。
使用OSSpinLock(已弃用,不推荐使用)
[/code] Objective-C
复制代码
1
#import <libkern/OSSpinLock.h>
2
3
OSSpinLock lock = OS_SPINLOCK_INIT;
4
5
void criticalSection() {
6
OSSpinLockLock(&lock);
7
// 临界区代码
8
OSSpinLockUnlock(&lock);
9
}
[size=3]使用pthread_spinlock_t(推荐方法)[/size]
[code]
复制代码
Objective-C
复制代码
1
#include <pthread.h>
2
3
pthread_spinlock_t spinlock;
4
5
// 初始化自旋锁
6
pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE);
7
8
void criticalSection() {
9
pthread_spin_lock(&spinlock);
10
// 临界区代码
11
pthread_spin_unlock(&spinlock);
12
}
13
14
// 在不再必要锁时烧毁它
15
pthread_spin_destroy(&spinlock);
在这个例子中,pthread_spinlock_t是POSIX线程库提供的自旋锁类型。使用pthread_spin_init函数初始化锁,并设置其为PTHREAD_PROCESS_PRIVATE,这意味着锁只能在同一进程的线程之间共享。在临界区前后分别调用pthread_spin_lock和pthread_spin_unlock函数来加锁息争锁。末了,当锁不再必要时,应调用pthread_spin_destroy来烧毁锁。
使用std::atomic_flag实现自旋锁(C++11及更高版本)
如果你在使用C++,而且你的编译器支持C++11或更高版本,你还可以使用std::atomic_flag来实现一个简单的自旋锁:
[code][/code] C++
复制代码
1
#include <atomic>
2
#include <thread>
3
#include <chrono>
4
#include <iostream>
5
6
std::atomic_flag lock = ATOMIC_FLAG_INIT;
7
8
void criticalSection() {
9
while (lock.test_and_set(std::memory_order_acquire)) {
10
// 自旋等待锁被开释
11
std::this_thread::yield(); // 提示调度器当火线程愿意放弃当前CPU资源的占用
12
}
13
// 临界区代码
14
lock.clear(std::memory_order_release); // 开释锁
15
}
在这个C++示例中,std::atomic_flag是一个原子的布尔类型,可以用作自旋锁的基础。test_and_set方法实验设置标志并返回其之前的值,如果返回true,则表示锁已经被占用,当火线程必要继承自旋等待。一旦获取到锁,线程就可以安全地进入临界区。完成临界区的操作后,使用clear方法来开释锁。
请留意,自旋锁适用于短时间的临界区掩护,由于在等待锁的过程中,线程会连续消耗CPU资源。如果临界区的执行时间较长大概锁的竞争很激烈,使用其他类型的锁(如互斥锁ÿ
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4