s=”heading” dat>
E _ ? SyncD = m A ] P – $o能的读者数为实 操作。
T U _() {
pthread_pan> obj可再次获取 -comment”>// 因>E h g x B / ] lass=”6hu-18696ss=”6hu-6960-mycode>两个方法,88-mypl” data-m调用。
utCond, mutex: mment”>#pragma class=”hljs-co了.比如下面的代eyword”>if
Log(@码,如果进行for线程 OSSpinLoc065-mypl" data-"hljs-keyword">; r u M
Y ! * 归锁。
"6hu">` - p 3 D占失效的。
-mypl" data-marmark="6hu">7 T ! C zd_int">// remove funt <=
NULL) data-mark="6hujs-comment">###--- 5 . n 2 ]="6hu-33284-mypata-mark="6hu">>UE_PRIORITY_LO class="warning-c lock(lass="6hu-28302js-string">@"生n>
OSAtomicDecr>objec/span> timedLoc" data-mark="6hde class="hljs e;
span>);
}
[recul" data-mark="6js-number">2f . } ? { U s-keyword">retuonary *dataCent>
我们都知道4-mypl" data-ma锁性能
void)prpthread_rwlock_="hljs-keyword"d C 和er.allo SyncDa="6hu">H 4 7 = js-keyword">sel"6hu">B $ q G De">// 因
wait用也NSCondiefore limit: D<="https://www.6"hljs-comment">套内部的存储。 = 0 A : a y a 2u-23478-mypl" dhu">` h l D d +ent">// Use mul+ [ ( eyword">id object, @"消费 s="hljs-keyword"hljs-keyword">">#endif542-mypl" data- data-mark="6hu="hljs-number">tion 加锁j Q 1 w U )。
pan>也可以看出 ockCount <= / Wakeup any thn>(why)_Ssync(disass="hljs bash ,自旋锁之所以 ----
for<-18816-mypl" da/code>源码中。
OSA-mark="6hu">m Objc_sync_exitc, strong)-mark="6hu">G _tW Z s 1 ypl" data-mark=^ . G 2 C R<) %use m/span>,查看其 v ! ifv _ *s="hljs-literal数据:
dispatch_pan class="hljsdispatch_get_glt_in">NSConditi="hljs-literal"pan class="6hu-在线程异步同时 作线程的相关增 33540-mypl" datss="6hu-3700-myternturn/ U ypl" data-mark=-mark="6hu">$ R和set8 (object);
SyncDutMutex, (value05/1589929042-2k="6hu">2 a { ,">nil)
pta-mark="6hu">l缓存中进行查找 >果 lockCount keyword">if {
34216-mypl" dat指的是传入需要 列:
self.concurass="6hu-16401- ? Q X ! tif 464-mypl" data->ot = newValue;,直到没有任何 行锁操作时,会 安全呢?其实并 k="6hu">- X 7 6" data-mark="6ha-mark="6hu">S y:key];
});
uten class="hljs-kkeyword">enumA 2 @ p t o"6hu-4680-mypl" co// Found a mtr_t()
pthread_mypl" data-markeading-4">互斥 ="6hu">; o x 1 le">];
和们可以看到,并 ), ^{
= i jn>如数组中的元 + L & @ q : yn class="6hu-32 ` W线程 w ?ondi有匹配的对象是条件锁,当满面例子中的= ta-mark="6hu">C 5 = z :ng">"id2data faan class="6hu-9ss="6hu-7848-my"id2data is bun funpl" data-mark="isguisedPtr! ) ` T t number">0F ^ K
#iflass="heading" 5184-mypl" datantPast)
}
open "hljs-number">0rk="6hu">5 k z s="hljs-keyword);
[cond-mypl" data-marect(SYNC_DATA_Dr">0 ||nt = i a width="1280" h加解锁的对象x*on:F , k ] [互斥dition {
? O Yu
ni: NSObject
// >thead操ljs objectivec 删改查方法,获 的一种上层封装 ock]两行34020-mypl" datG [ p Z | b| u Zljs objectivec e {
程不安全data-id="headin都没有找到的话 Y c lemeoutMute// 存入 t X L } XL H X D e %LL_BEGIN
@intercontention amon1.testsiass="6hu-4187-mmark="6hu">) ` lass="6hu-34191-30740-mypl" dact) {
r_async}
1 p 3 l ] ta-mark="6hu">S/span>合是有效 E h e X 740-mypl" data->适用于生产者消s="6hu-38280-myclass _asyn any threads wa
ic
☞n>(/逻辑的前后,加 ="6hu">9 6 L O<可重入锁,同一 ] ^read_hu">a @ & C -T _ hlock("6hu-2331-mypl"ark="6hu">: @ ache) cache = f直接通过调用方 >YES);
cbarrier_async(snc lock(lock]和1做了 class="6hu-795的⾃旋锁,只允 hu-17460-mypl" ypl" data-mark=所以这是一个递 u-12036-mypl" dm g U u t k@ n 5 g d 0 Nruct ali/h3>
这步操 6-mypl" data-ma写者。在读写锁 fair_lockstond, trb">X E 5 I o `a X6hu-6460-mypl" span class="6hu" data-mark="6h的任务不会忙等 文章JAVAmark="6hu">u l n class="hljs-k
}
open func er(t递归锁:下去, number">0@ k 3 u m2data并通过 tls 保存的。
i } M/code>是对#endif来ass="heading" d-mark="6hu">U ./code>取出// atnil)
tls_set_diss="6hu-30894-m> value){
[recupan>nchronized< iOS底层学习 - 28671-mypl" dateyword">returnobjectypl" data-mark=
是就说明其线程 YNC_Nz $ E 6 s享资源的访问者 的情况下,才可 te(capacity:#if data-mark=”6hu
– (i & p@synil
yword”>ifN % d ,pan>
#ion: 55-mypl” data-m v – W X 9a & L U
@ienterekeyword">return_sync_ento f 3 码在obj (ob// a"># K T eading-15">1.2 是保证setdata-mark="6hu"写入缓存
T U _() {
pthread_pan> obj可再次获取 -comment”>// 因>E h g x B / ] lass=”6hu-18696ss=”6hu-6960-mycode>两个方法,88-mypl” data-m调用。
Log(@码,如果进行for线程 OSSpinLoc065-mypl" data-"hljs-keyword">; r u M
Y ! * 归锁。
"6hu">` - p 3 D占失效的。
-mypl" data-marmark="6hu">7 T ! C zd_int">// remove funt <=
NULL) data-mark="6hujs-comment">###--- 5 . n 2 ]="6hu-33284-mypata-mark="6hu">>UE_PRIORITY_LO class="warning-c lock(lass="6hu-28302js-string">@"生n>
OSAtomicDecr>objec/span> timedLoc" data-mark="6hde class="hljs e;
span>);
}
[recul" data-mark="6js-number">2f . } ? { U s-keyword">retuonary *dataCent>
我们都知道4-mypl" data-ma锁性能
void)prpthread_rwlock_="hljs-keyword"d C 和er.allo SyncDa="6hu">H 4 7 = js-keyword">sel"6hu">B $ q G De">// 因
wait用也NSCondiefore limit: D<="https://www.6"hljs-comment">套内部的存储。 = 0 A : a y a 2u-23478-mypl" dhu">` h l D d +ent">// Use mul+ [ ( eyword">id object, @"消费 s="hljs-keyword"hljs-keyword">">#endif542-mypl" data- data-mark="6hu="hljs-number">tion 加锁j Q 1 w U )。
pan>也可以看出 ockCount <= / Wakeup any thn>(why)_Ssync(disass="hljs bash ,自旋锁之所以 ----
for<-18816-mypl" da/code>源码中。
OSA-mark="6hu">m Objc_sync_exitc, strong)-mark="6hu">G _tW Z s 1 ypl" data-mark=^ . G 2 C R<) %use m/span>,查看其 v ! ifv _ *s="hljs-literal数据:
dispatch_pan class="hljsdispatch_get_glt_in">NSConditi="hljs-literal"pan class="6hu-在线程异步同时 作线程的相关增 33540-mypl" datss="6hu-3700-myternturn/ U ypl" data-mark=-mark="6hu">$ R和set8 (object);
SyncDutMutex, (value05/1589929042-2k="6hu">2 a { ,">nil)
pta-mark="6hu">l缓存中进行查找 >果 lockCount keyword">if {
34216-mypl" dat指的是传入需要 列:
self.concurass="6hu-16401- ? Q X ! tif 464-mypl" data->ot = newValue;,直到没有任何 行锁操作时,会 安全呢?其实并 k="6hu">- X 7 6" data-mark="6ha-mark="6hu">S y:key];
});
uten class="hljs-kkeyword">enumA 2 @ p t o"6hu-4680-mypl" co// Found a mtr_t()
pthread_mypl" data-markeading-4">互斥 ="6hu">; o x 1 le">];
和们可以看到,并 ), ^{
= i jn>如数组中的元 + L & @ q : yn class="6hu-32 ` W线程 w ?ondi有匹配的对象是条件锁,当满面例子中的= ta-mark="6hu">C 5 = z :ng">"id2data faan class="6hu-9ss="6hu-7848-my"id2data is bun funpl" data-mark="isguisedPtr! ) ` T t number">0F ^ K
#iflass="heading" 5184-mypl" datantPast)
}
open "hljs-number">0rk="6hu">5 k z s="hljs-keyword);
[cond-mypl" data-marect(SYNC_DATA_Dr">0 ||nt = i a width="1280" h加解锁的对象x*on:F , k ] [互斥dition {
? O Yu
ni: NSObject
// >thead操ljs objectivec 删改查方法,获 的一种上层封装 ock]两行34020-mypl" datG [ p Z | b| u Zljs objectivec e {
程不安全data-id="headin都没有找到的话 Y c lemeoutMute// 存入 t X L } XL H X D e %LL_BEGIN
@intercontention amon1.testsiass="6hu-4187-mmark="6hu">) ` lass="6hu-34191-30740-mypl" dact) {
r_async}
1 p 3 l ] ta-mark="6hu">S/span>合是有效 E h e X 740-mypl" data->适用于生产者消s="6hu-38280-myclass _asyn any threads wa
ic
☞n>(/逻辑的前后,加 ="6hu">9 6 L O<可重入锁,同一 ] ^read_hu">a @ & C -T _ hlock("6hu-2331-mypl"ark="6hu">: @ ache) cache = f直接通过调用方 >YES);
cbarrier_async(snc lock(lock]和1做了 class="6hu-795的⾃旋锁,只允 hu-17460-mypl" ypl" data-mark=所以这是一个递 u-12036-mypl" dm g U u t k@ n 5 g d 0 Nruct ali/h3>
这步操 6-mypl" data-ma写者。在读写锁 fair_lockstond, trb">X E 5 I o `a X6hu-6460-mypl" span class="6hu" data-mark="6h的任务不会忙等 文章JAVAmark="6hu">u l n class="hljs-k
}
open func er(t递归锁:下去, number">0@ k 3 u m2data并通过 tls 保存的。
i } M/code>是对#endif来ass="heading" d-mark="6hu">U ./code>取出// atnil)
tls_set_diss="6hu-30894-m> value){
[recupan>nchronized< iOS底层学习 - 28671-mypl" dateyword">returnobjectypl" data-mark=
是就说明其线程 YNC_Nz $ E 6 s享资源的访问者 的情况下,才可 te(capacity:
– (i & p@synil
yword”>ifN % d ,pan>
#ion: 55-mypl” data-m v – W X 9a & L U
@ienterekeyword">return_sync_ento f 3 码在
obj
(ob// a"># K T eading-15">1.2 是保证setdata-mark="6hu"写入缓存
selfself.t// 多个线程需要s.
@"线程 3"pl" data-mark="ljs-keyword">if == v 3 n
时只能有_cachE $ W : @ != 0547-mypl" data-dition 的值为 26hu-9968-mypl" -mark="6hu">/ rhu">G / s )参考 1
[condass="hljs-comme同⼀公共资源( hljs-keyword">rnditionLock loc% S f 2 H xx J 7 y决问题,因为&hljs-comment">/pan>cond: timeonumber">0case"hljs-keyword">tex = _MutexPoi;
✅@l" data-mark="6attrs)
pthread_>. X w E * ] ) 概念
staticos__conddata-mark="6hu"lass="6hu-21725span class="hljhile _th-mypl" data-mar0-mypl" data-mas-built_in">NSL;全局哈希表d;
fo一块内存发生读 span class="6hu&lock);
// ionLock unlockWnterDio / ! o Kn>kp-&g5 _ + de class="hljs N _ 2 f i不进行 ----
Thread A:1/span>tion
_con {
S{ B 6hu-28602-mypl"code class="hljdata-mark="6hu"
// 写数据
- (v行.现在这个条件">a l O h A ( q"heading-6">自 synchronized{ En>Key:(NSStringss="hljs-commen>ck];
};
的优先级反转。
在加 407-mypl" data-6hu-21982-mypl" o ? 7 lass="hljs-commx $ D j C ` nl I D read: _swift_CFtivec copyable"享资源,最⼤可 ;
,使用 NSLock就ConditionLock3. >通过之前篇章的 = id2data(obj, B N Intss="hljs-keyworother thread.ondiead_mutex_unlocss="hljs-built_ypl" data-mark=="6hu-18700-mypk
会造成 /code>对象只有 data-mark="6hu"nt">// 只有创建READS using thiist() : data(7 z 6 "6hu-11501-mypls-comment">// eItem *item/ U f o * ]U g W i 6 * Q类rettch_asyncB 8 W Y 8} a 分类方式X C a y Q qNSObjec];
,加一把同步锁 wrlclassnil
,从 {
fastCacheOcchljs-keyword">idata-mark="6hu"e>和unlocing">@"等待 coupan class="6hu-" data-mark="6h6hu">} ; B (uintptr_t)tlss="hljs-literalH ?-----eca
由于>
public overri停的alloc费者模式
ock(whenConditiS [个是selfhljs-keyword">rhu-19467-mypl" an>te(capacity:) {
pthread_mut ACQUIRE:
item-/span>y% 从而释#if os(mace) -> (why != ACding-14">1.1NSLogP z q ~ 2 - 10-mypl" data-mljs-comment">//的安全。
所以dispatch_an class="6hu-3---------------ng>并发队列+disde>@synchronizepan>-----------hu">T ) t 2 C xic SyncDspan>d B:1
Thre直处于忙等待状 elf.num);
}
});/span> (i =
而Key:key];
});取锁。
Z 4 sul
t;datthljs-keyword">brss="6hu-10764-me>NSCondition);j 5 F . , consumer];
});不是的话,则直 a-mark="6hu">E span class="6hu&& (p-&hu">( U j B v m-number">1[ 1 1 4 E="6hu">F d M ; >1 ` ; & Y s[ L 8ing" data-id="h6hu-19851-mypl""hljs-keyword">copyable"> N- | ,c x a J s = ) Y / ##endi作是检查所有线 G_THREAD_ERROR;ata-mark="6hu">mment">// 初始 判断,如果obj为nt">// 检查每线ta-mark="6hu">Lypl" data-mark=忙等待。⼀旦获 -5">互斥锁与自 hu">g ^ a { @ &lass="hljs-builpan class="hljsan>,value);
tesatal(nit(mutex, nnc unlock() {
_ass="hljs-litergt;所有线程->="6hu-952-mypl";
// 异步递归调;
result->nej T M a ~F 2 opinLock被 ypl" data-mark=);
在寻找源de>是否为n>init(timeoutCjs-number">1/ T * fche->list[i]>的锁,这个锁保lB Sss="6hu-34714-m作发出时,如果 lass="6hu-6500-s-keyword">inz t m *,但是初始化的 e
)锁。如能保证多条线程 ), ^{
[), ^{
iass="hljs-keywo02-mypl" data-mn>), ^{
[[_lock class="hljs-kein">testde>结构的数据,执行下面的代码
✅~ y N $ A rom fast cache(di class="6hu-114数据访问
@prop<中执行加锁的相<同实现。可以看 { : nd_bn class="6hu-28n class="6hu-15k);
// 读-尝试 kWhenCondition:传送门:
: S - 7 fif
U
}
}
...
}
CoreFunda="6hu-456-mypl"ypl" data-mark=s="hljs-keywordcode>LOCK_FOR_O这片文章->不-mypl" data-maran>程 B 在执行 来实现nt;
result = damport <Foundlass="6hu-21357pan class="6hu-6hu">d h 2 . & >n
是一个 n>e( usage why)
{
span class="hljn func { h ber">3
class="hljs-key替代,是一个互 class="hljs-str---------------于底层原理,我 n> *se>是类似的,并 hljs-literal">n且需要注意传入 cond.unlock()
}> {
0g-7">1. OSSpinL
中都首先bash copyable">="6hu">0 : 5 j n> obj)
{
);
testMe6hu-7267-mypl" 6hu-4732-mypl" ec copyable">--an class="hljs-ss="6hu-6966-mymypl" data-mark关封装的pthead -------------什么是锁dudata-id="headins="hljs-keyworda-id="heading-1class="6hu-3752分u W C d"6hu">= L l , J阻塞 W d b ,-mark="6hu">` .-comment">// 没 data-id="headi实现,发现| nS底层学习 - 多 u-14883-mypl" dls_g034-mypl" data-mk="6hu">J M z }面,一.tickfor锁的对象,在其 情况
? z r 0 # g/ 如果obj为空,ilSync) {
_objc 6成死锁mypl" data-marknt i = <)PTHREAD_MUTEX_>typedefnt">// 线程安全锁出现优先级反 6hu-11362-mypl"线程的多次创建 ⽐ 如全局变量)会被打乱(5 G a F T f current_queue;
hljs-keyword">eng-8">2. atomic class="6hu-998number">1{objectivec copy处理
我 class="hljs-bustUnused = p;
}ord">goto0)
}
puljs bash copyabass="6hu-4884-mY w 1 fos="hljs-keywordjs-keyword">clade>锁对象
iO”>c L T 7 ! M ?/span>, offset,” data-mark=”6h6hu”>? W y并发队 pan class=”hljs> (item->的一放掉锁。
ass=”hljs-comme! Kerty 成传入值为空的 js-number”>1r x G >NSpthread_mut() {
pthread_muan>解了Sy锁失败funwhilread_mutex_initd) {
if~an class="6hu-7ePointer.allocaan class="hljs- 7 Q + + @ ; p<源码,我们可以 an class="6hu-2ed].lockCount =6hu">O q 5 H j ypl" data-mark=">return="6hu-13068-myp~ ^ sx_d时候可以使用递 缓存中删除1class="6hu-1675! x G s v对象时, 的工具。
if% N e Bspan>
lockCountlass="hljs-keyw g M : | h v E< q S 4 & ~ ainit, // All RValue, ptrdiff_ I ! 3rkeyword">self时)
}
deinit {
pte var timeoutM="6hu-28830-mypjs-keyword">cas9575-mypl" datamypl" data-markself()
_cond.un?
}
er_aass="hljs-keywo(!atomic) {
// "hljs-comment">dition 为 1 的 635-mypl" data-jec---pan>rifss="6hu-22828-m条件锁。
k G d h V 8 ber">1
)
k="6hu">x u ^ v锁时,线程会一 ">K ( g bfunc tryLock(wh
)object;word">if
an class="hljs-hu-11373-mypl" class="6hu-6237s objectivec coe>加线程数的封 >retu-mypl" data-mar操作,那同时都 ass="6hu-32823-
ThrealePointmypl" data-markid newValUnused != /pre>
在具体--_ bRITY_HIGH, *slot;
class="hljs-com特定类型数据的 i 0 , C e m x
- (id)wy_);
}
NSLo读写锁,否则它 cate(capacity: 23730-mypl" dat了一个全局的哈 mark="6hu">Y o 700-mypl" data-锁。
8 F ~ n>read cache of v # ! bs="hljs-keywordan> result = OB只有一个递归锁 u-22420-mypl" d y A /--"hljs-comment">K l L Q L h7664-mypl" dataSLockin alloc]锁在线程获取锁 >ct:(id)obj fa-comment">// Cha-mark="6hu">{ an>) {
前面// 打印结果)
withUnsafde>的判断,如果 也就是线程不安R f ;ad_kCount--;
strucit];
i;
co递归获取都是由 QUIRE are C o 3 d C y 0 /span>w ACQUIREan> object, // pan>
✅true
}
a-mark="6hu">w 要循环,外界的 ypl" data-mark=data-mark="6hu"ad_muter | W B w ZutCo~ h A o Q> / * r f &
guacode>atomicclass="6hu-2511唤醒所有正在等 // number of THcachopan class="hljs-ljs-number">1
="hljs-comment"meSpecFrom(date放的: 线 veLock
就-操作是唤醒一 ex_i& F M 0 ^ 6ir_lock
>t Y g ? % h 6ta-mark="6hu">Zlass="hljs-keywspan>型的对象。一定要注意传ta-mark="6hu">W/span>
✅
pthread的话,就会造成 while the objecs="hljs-keyword就阻塞等待. 而 de class="hljs keyword">idgt;ob量,也是对Method k="6hu">0 [ )5. NS p;
SyncData* fan class="hljs-f d tatic^ 3timeo>V 1 ^ m销毁
pthread_rw>o } v f tdispatch_as< m f uon-mark="6hu">E q递归锁和非递归 ypl" data-mark=k="6hu">9 4 j & == ,很多锁 omic, strong) d加锁
pthread_rw="6hu">| N - o before: Date.diata-mark="6hu">ta">#j 3 K @span class="hlj"6hu">N . 2 ~ [ListZ 4 i 9 {
int写者或读者。如 keyword">void/ R P slass="heading" t;objc_object&g~ 9 y Y @的效 可以考虑使用条 ,变成迟迟完不 code>协议,也有 {
x { G F I }nchr锁的作 ---------------pan class="hljsark="6hu">C w x中是否有匹配的 data-mark="6hu"6hu-9600-mypl"esult->threaif rac = [NSMuta -> Bool {
<>通过这两个方
锁 -- 是 class="hljs-cox)
D ? @ 7Co
self享资源进) sDataL)
..
n v T M y 1 | il;
}
SyncDact *k L 1F线程缓 哈希表查找
写-尝试加锁
pthkCount 减 1,并enterfor读写forde>lock
="6hu-36351-myps-keyword">casei>
-
a="6hu-28551-myphronized
[ o *nt"hljs-built_in" class="6hu-375锁是一种非强制
因为互斥 w 1-cack(whenConditionget
方法 ,而os_unondition, beinter(to:mark="6hu">, ? read = N * -built_in">NSLo操作,并生成了 线程,加锁两次 >tls
封装n class=”6hu-13_in”>dispatch_ass=”hljs-keywor>
首先我们还nterface WY_RWLn>关逻辑即可。<对objnil |ion unlock];
}
q . t k w
}
;u”>L F l o P o js-keyword”>els和已经锁住的线 u-33456-mypl” d的结果:
创获 资料
staticos__conddata-mark="6hu"lass="6hu-21725span class="hljhile _th-mypl" data-mar0-mypl" data-mas-built_in">NSL;全局哈希表d;
fo一块内存发生读 span class="6hu&lock);
// ionLock unlockWnterDio / ! o Kn>kp-&g5 _ + de class="hljs N _ 2 f i不进行 ----
Thread A:1/span>tion
_con {
S{ B 6hu-28602-mypl"code class="hljdata-mark="6hu"
// 写数据
- (v行.现在这个条件">a l O h A ( q"heading-6">自 synchronized{ En>Key:(NSStringss="hljs-commen>ck];
};
的优先级反转。
在加 407-mypl" data-6hu-21982-mypl" o ? 7 lass="hljs-commx $ D j C ` nl I D read: _swift_CFtivec copyable"享资源,最⼤可 ;
,使用 NSLock就ConditionLock3. >通过之前篇章的 = id2data(obj, B N Intss="hljs-keyworother thread.ondiead_mutex_unlocss="hljs-built_ypl" data-mark=="6hu-18700-mypk
会造成 /code>对象只有 data-mark="6hu"nt">// 只有创建READS using thiist() : data(7 z 6 "6hu-11501-mypls-comment">// eItem *item/ U f o * ]U g W i 6 * Q类rettch_asyncB 8 W Y 8} a 分类方式X C a y Q qNSObjec];
,加一把同步锁 wrlclassnil
,从 {
fastCacheOcchljs-keyword">idata-mark="6hu"e>和unlocing">@"等待 coupan class="6hu-" data-mark="6h6hu">} ; B (uintptr_t)tlss="hljs-literalH ?-----eca
由于>
public overri停的alloc费者模式
ock(whenConditiS [个是selfhljs-keyword">rhu-19467-mypl" an>te(capacity:) {
pthread_mut ACQUIRE:
item-/span>y% 从而释#if os(mace) -> (why != ACding-14">1.1NSLogP z q ~ 2 - 10-mypl" data-mljs-comment">//的安全。
所以dispatch_an class="6hu-3---------------ng>并发队列+disde>@synchronizepan>-----------hu">T ) t 2 C xic SyncDspan>d B:1
Thre直处于忙等待状 elf.num);
}
});/span> (i =
而Key:key];
});取锁。
Z 4 sul
t;datthljs-keyword">brss="6hu-10764-me>NSCondition);j 5 F . , consumer];
});不是的话,则直 a-mark="6hu">E span class="6hu&& (p-&hu">( U j B v m-number">1[ 1 1 4 E="6hu">F d M ; >1 ` ; & Y s[ L 8ing" data-id="h6hu-19851-mypl""hljs-keyword">copyable"> N- | ,c x a J s = ) Y / ##endi作是检查所有线 G_THREAD_ERROR;ata-mark="6hu">mment">// 初始 判断,如果obj为nt">// 检查每线ta-mark="6hu">Lypl" data-mark=忙等待。⼀旦获 -5">互斥锁与自 hu">g ^ a { @ &lass="hljs-builpan class="hljsan>,value);
tesatal(nit(mutex, nnc unlock() {
_ass="hljs-litergt;所有线程->="6hu-952-mypl";
// 异步递归调;
result->nej T M a ~F 2 opinLock被 ypl" data-mark=);
在寻找源de>是否为n>init(timeoutCjs-number">1/ T * fche->list[i]>的锁,这个锁保lB Sss="6hu-34714-m作发出时,如果 lass="6hu-6500-s-keyword">inz t m *,但是初始化的 e
)锁。如能保证多条线程 ), ^{
[), ^{
U
}
}
...
}
CoreFunda="6hu-456-mypl"ypl" data-mark=s="hljs-keywordcode>LOCK_FOR_O这片文章->不-mypl" data-maran>程 B 在执行 来实现nt;
result = damport <Foundlass="6hu-21357pan class="6hu-6hu">d h 2 . & >n
是一个 n>e( usage why)
{
span class="hljn func { h ber">3
class="hljs-key替代,是一个互 class="hljs-str---------------于底层原理,我 n> *se>是类似的,并 hljs-literal">n且需要注意传入 cond.unlock()
}> {
0g-7">1. OSSpinL
中都首先bash copyable">="6hu">0 : 5 j n> obj)
{
);
testMe6hu-7267-mypl" 6hu-4732-mypl" ec copyable">--an class="hljs-ss="6hu-6966-mymypl" data-mark关封装的pthead -------------什么是锁dudata-id="headins="hljs-keyworda-id="heading-1class="6hu-3752分u W C d"6hu">= L l , J阻塞 W d b ,-mark="6hu">` .-comment">// 没 data-id="headi实现,发现| nS底层学习 - 多 u-14883-mypl" dls_g034-mypl" data-mk="6hu">J M z }面,一.tickfor锁的对象,在其 情况
? z r 0 # g/ 如果obj为空,ilSync) {
_objc 6成死锁mypl" data-marknt i = <)PTHREAD_MUTEX_>typedefnt">// 线程安全锁出现优先级反 6hu-11362-mypl"线程的多次创建 ⽐ 如全局变量)会被打乱(5 G a F T f current_queue;
hljs-keyword">eng-8">2. atomic class="6hu-998number">1{objectivec copy处理
我 class="hljs-bustUnused = p;
}ord">goto0)
}
puljs bash copyabass="6hu-4884-mY w 1 fos="hljs-keywordjs-keyword">clade>锁对象
iO”>c L T 7 ! M ?/span>, offset,” data-mark=”6h6hu”>? W y并发队 pan class=”hljs> (item->的一放掉锁。
ass=”hljs-comme! Kerty 成传入值为空的 js-number”>1r x G >NSpthread_mut() {
pthread_muan>解了Sy锁失败funwhilread_mutex_initd) {
if~an class="6hu-7ePointer.allocaan class="hljs- 7 Q + + @ ; p<源码,我们可以 an class="6hu-2ed].lockCount =6hu">O q 5 H j ypl" data-mark=">return="6hu-13068-myp~ ^ sx_d时候可以使用递 缓存中删除1class="6hu-1675! x G s v对象时, 的工具。
if% N e Bspan>
lockCountlass="hljs-keyw g M : | h v E< q S 4 & ~ ainit, // All RValue, ptrdiff_ I ! 3rkeyword">self时)
}
deinit {
pte var timeoutM="6hu-28830-mypjs-keyword">cas9575-mypl" datamypl" data-markself()
_cond.un?
}
er_aass="hljs-keywo(!atomic) {
// "hljs-comment">dition 为 1 的 635-mypl" data-jec---pan>rifss="6hu-22828-m条件锁。
k G d h V 8 ber">1
)
k="6hu">x u ^ v锁时,线程会一 ">K ( g bfunc tryLock(wh
)object;word">if
an class="hljs-hu-11373-mypl" class="6hu-6237s objectivec coe>加线程数的封 >retu-mypl" data-mar操作,那同时都 ass="6hu-32823-
ThrealePointmypl" data-markid newValUnused != /pre>
在具体--_ bRITY_HIGH, *slot;
class="hljs-com特定类型数据的 i 0 , C e m x
- (id)wy_);
}
NSLo读写锁,否则它 cate(capacity: 23730-mypl" dat了一个全局的哈 mark="6hu">Y o 700-mypl" data-锁。
8 F ~ n>read cache of v # ! bs="hljs-keywordan> result = OB只有一个递归锁 u-22420-mypl" d y A /--"hljs-comment">K l L Q L h7664-mypl" dataSLockin alloc]锁在线程获取锁 >ct:(id)obj fa-comment">// Cha-mark="6hu">{ an>) {
前面// 打印结果)
withUnsafde>的判断,如果 也就是线程不安R f ;ad_kCount--;
strucit];
i;
co递归获取都是由 QUIRE are C o 3 d C y 0 /span>w ACQUIREan> object, // pan>
✅true
}
a-mark="6hu">w 要循环,外界的 ypl" data-mark=data-mark="6hu"ad_muter | W B w ZutCo~ h A o Q> / * r f &
guacode>atomicclass="6hu-2511唤醒所有正在等 // number of THcachopan class="hljs-ljs-number">1
="hljs-comment"meSpecFrom(date放的: 线 veLock
就-操作是唤醒一 ex_i& F M 0 ^ 6ir_lock
>t Y g ? % h 6ta-mark="6hu">Zlass="hljs-keywspan>型的对象。一定要注意传ta-mark="6hu">W/span>
✅
pthread的话,就会造成 while the objecs="hljs-keyword就阻塞等待. 而 de class="hljs keyword">idgt;ob量,也是对Method k="6hu">0 [ )5. NS p;
SyncData* fan class="hljs-f d tatic^ 3timeo>V 1 ^ m销毁
pthread_rw>o } v f tdispatch_as< m f uon-mark="6hu">E q递归锁和非递归 ypl" data-mark=k="6hu">9 4 j & == ,很多锁 omic, strong) d加锁
pthread_rw="6hu">| N - o before: Date.diata-mark="6hu">ta">#j 3 K @span class="hlj"6hu">N . 2 ~ [ListZ 4 i 9 {
int写者或读者。如 keyword">void/ R P slass="heading" t;objc_object&g~ 9 y Y @的效 可以考虑使用条 ,变成迟迟完不 code>协议,也有 {
x { G F I }nchr锁的作 ---------------pan class="hljsark="6hu">C w x中是否有匹配的 data-mark="6hu"6hu-9600-mypl"esult->threaif rac = [NSMuta -> Bool {
<>通过这两个方
锁 -- 是 class="hljs-cox)
D ? @ 7Co
self享资源进) sDataL)
..
n v T M y 1 | il;
}
SyncDact *k L 1F线程缓 哈希表查找
写-尝试加锁
pthkCount 减 1,并enterfor读写forde>lock
="6hu-36351-myps-keyword">casei>
-
a="6hu-28551-myphronized
[ o *nt"hljs-built_in" class="6hu-375锁是一种非强制
因为互斥 w 1-cack(whenConditionget
方法 ,而os_unondition, be
封装n class=”6hu-13_in”>dispatch_ass=”hljs-keywor>
首先我们还nterface WY_RWLn>关逻辑即可。<对objnil |ion unlock];
}
q . t k w
}
创获 资料
在面试">else {/code> 时间片。span class="6hu>
br" data-mark="6hy collide with pan class="6hu-class="heading"an>ad_rwlock_wrtion: : $ . ] f S 3lt->threadCo同步锁,保证 geCount);
)
private va-mark="6hu">8 ]eadCount = 0 , 同一个数据的访 性进行同时的操 ondition6hu">H 0 $ c V span class="6hu0-mypl" data-ma_get_direct(SYNOccupied =
实现了n>;
✅S Q ; 全。
关 /span>件读写锁
dispatch_sync( data-mark="6hure>
既然e:n class="6hu-16()
internal va<// n class="hljs-kf (item-yword">enumn class="hljs-t)
_cond.unlock(ck();
al var _th">j + @ ! Otr/span>ockp = &a造成死锁,可用<代码,多线程调 个读者。可以使 pan class="hljsspan> usage why9845-mypl" data-mypl" data-marSRecursiveLock<,才能进行操作 ue, s `"hljs-keyword">able">void objcutex.lock();
} t a e 4oa-mark="6hu">R 护了一个哈希表 re>
YES dRE: {
ord">for O = . ving" data-id="h是使用ato据,并进行快速 者,读者只对共 情况下,使用哪 e(z C T % w *rk="6hu">K 7 f inlock_t lock;
-21534-mypl" daOS 锁
return调用或者不适用<1 f 6 d d u f
nextDaomment"">// Savepan class="hljs了objc_sy,其它试图获取 也就是说是必须⾃旋 k 5ondJ T 4
...
}
A M">break;>Data
类 `据字典l" data-mark="6
}
[tbo">// Save in faad_mutex_trylocU L s .Sata-mark="6hu">ata* id2data("NIL SYNC D
result->thr [_lock unl id obj;
// 同 = tiqu">` Q u b K odata-mark="6hu"J 2 yemaan class="hljs-6hu">y v p * r ^ c
既然我们在 0-mypl" data-mazed
解决<="hljs-keyword"ss="6hu-34428-m用来解决的就是 usags-number">1a W # 5 I --------------- d d H qGesult) data-id="headin>);
(I P r Qu">8 & r s W n n>);
}
的封装3-mypl" data-maDataLists[obj].an class="6hu-2hu.cc/wp-contenS ! ~ ckDest*ead_cond_broad<响的时候,为了 hu">L ~ x . U Zan class="hljs-to & u Strta;
lockCount =。
互 说主要是两个方
✅ SyncData* 信大家都拜读过 o O F V 同1)
eturn reFound a mat
y ` n)
priva
系列文章4016-mypl" data解决死锁的问题 .ticketC由于自旋锁获取 --------------- 1;
NS,可/span>
[conditiper init];nil6hu-4356-mypl" ---------------ng *)key{
// 异-literal">true<;threadCount);
-mypl" data-marswitch);
}
G [ d k #L R 6/gt;mutex) recur>;
new (&ax C % @];
3 / J 1 ~ 8 Ppan class="hljs的,所以造成了 lass="hljs-numb31465-mypl" dat-19494-mypl" daobjnd.u6hu-38294-mypl"te()
deallocate------//注意消费行 ncD// ">p 7 8 V |x)
}
open vajs-string">"Thrta-mark="6hu">Zmp;LOCK_FOR_OBJhu">y 9 ; D 1 _ont>,它把对共 != object) _obpan>
✅] 3 5 1} data-mark="6hu alignof(SyncDapatch_barrie6hu">U 5 Q K w 。比如刚才的代 "6hu-35112-mypl>2
线程 M 2 r候Lock。总结来说 "6hu">A 9 S 2if js-literal">truvec copyable">NSPATCH_QU// 保证正 >和NSCond2 b安全 g 8cond168-mypl" data- class="hljs-co6. os_unfair_los="6hu-12012-myk="6hu">o _ : 1rn resul果错误等情况。 : Releass-number">0if (!cspan class="hljtch_semaph
✅in">NSLocking实现>☞ iOS底层学习 class="6hu-236的代码
, SyncLisbjc_objereturn /span> CHECK:
) k /,就比如下面的itionLocki ypl" data-mark=加forx---------------保存的哈希表中<& B 5 0 5 ; ,ifid
不是递归锁,那 n NT_DIpan class="hljs// 解锁,并将 ctry`() -> Bount+ConditionLockbool; Bool {
s="hljs-keywordk="6hu">s ` : q
[co断点Data *)tlass="heading" , o $ ; c l |/ ( ode> 和 ou">y M 0 j Y N 69be0c2a221389.mutex_lock(mute &timeout) 的源码,通过打 n>)
mu&gn class="hljs-k u N & W o $cate(cic convenience overridess="heading" dacode>atomicif ; =并在ass="hljs-comme init() {
; 7 # E x & iad B:2
Thread ASLock实 问 同步 (ass="6hu-23712-存入线程缓存d 1 6<---------------">Y h +->` x H x nP ospan>);
[condit a 5 h i A y 5 x m } ^
} Z E C 2728-mypl" data1() {
p="6hu-21165-myp"hljs bash copy多线程之GCD初探t">// 通过tls相span>层实现其实>NSRenumstati行加锁和解锁的 hljs-literal">nan>ECK and rec<>- : ` L ( a--------NSLock lock(an class="6hu-3ad = pth要注意传入 js-comment">// 装,继承N-mypl" data-mar的,如果是有很 旋锁
: h o p H, DIcond_是在12-mypl" data-m-mypl" data-mar6hu">Q & ? # W alloc] init];
d条件锁,m 8-mypl" data-maark="6hu">{ N Ps="hljs objecti data-mark="6huypl" data-mark=tion all
// ...
NSLocki="hljs-keyword"span>;
cache-&geure<
Nockquote>
e b Z & eading-11">互斥">) ~ I Z q L ;ta-mark="6hu">`删改查
和exitconditionLoc. b ? h et// atomic bmypl" data-mark), ^{
~ 则2#endifpinlock_t
此步">& l ( 4 M0), t o= C i de>
i data-mark="6hu/span>,从而加 oadcast
code>NSL turn done;
}
W f508-mypl" data-="6hu-14755-myp ) B P i : (resuypl" data-mark=同一个对象,下 mypl" data-mark class="hljs-nuata-mark="6hu">能#if os(macOS) _ = lock(bef// rem以根据锁的状态 js-comment">// pan class="hljsdata-mark="6hu"873-mypl" data-apacity: d { t + h P ] Y = { 1 k<20-mypl" data-mu">^ x J ? x S js-keyword">whilass="hljs-keyw要保证递归调用 span>OS)nilv ^ 5data-mark="6hu"
}
< = a Zc<但是操作结构复 d">if (
n A @break;
" data-mark="6hcode>的基础上添讲过,lV U +可以完美解 n>
signal当我们对同一个d, ptrdiff_t ofass="hljs-keywol" data-mark="6>H O d Fspan class="hljmypl" data-marke > 0) {
NSLstcache is bug0 A b b Z wan class="6hu-3 , lock(fread_mutex_init func wait(unti
OSSpidispapl" data-mark="ad != L h="6hu-12210-myp"6hu">t n ( p /an>; i++) {
ondition lock]span class="6huy, bool mutabb == RELEASE) ||">` {
}an>
线程
j Y 4mic是否 i>
t的,⼀个读写锁 rect(SYNu Y @4310-mypl" data方法获取是否有 a-mark="6hu">2 mark="6hu">? & class="6hu-329mp;lock);
();
id的 SyncData 才 class="hljs-bu
--------------,锁的特性等进 "> ` S ;的问题,总结来 H_QUEid* y 0 ljs-number">1k >l U . ( *nd, uark="6hu">/ 5 Dspan>)7 G *装,由于未开源 ass="hljs-builtan class="hljs- 6-mypl" data-mas="hljs-string">
// 所以 N4170-mypl" data RELEASEjs-number">10d o % N g 。当获取锁操作 trylock(mutex) public override6-mypl" data-ma---------------span>_sync_& Z W 2ss="6hu-8853-my程 A 需要 r6hu-24336-mypl"a-mark="6hu">s ass="6hu-29898- class="6hu-972>@ . J b . ) _<"6hu">v t @ f D,这种情况下, class="6hu-8085是自旋锁的忙等 pan class="hljs-mark="6hu">t Q"hljs-comment">lotlock.unlock(种封装。c并列的关系,而 span class="hlj列+dispatch_bar) . .源,于是绕过了 ="6hu-2562-mypln class="hljs-k>非递归锁:不可
open func lock init];
false.ticket.cc/wp-content/ilt_in">dispatcquire) sult->threadt_in">NSRecursipl" data-mark="u">r D ` *d u">] X Cn>);
} ) )
fire>
具体的用 ">sizeof iintA ^ = A 9 Xe ^ Bdows)RE);
asserch_semaphoreter 的安全
spi="6hu-6958-myplar name: Stringd">if ( || os(Win class="6hu-402 class="hljs-me="hljs-string">PropertyLocks[s(^testMethod)(<通过代码我们5 R V w m + d uilt_in">dispat。因为处于等待 span>estMethod(6hu-8610-mypl" blockquote clasn>used;
result-roadcast(cond) 一线程上是安全 rd">self-mypl" data-marlass="hljs-keywOS10之后OSS
% 2 !<用条件锁来完成 " data-mark="6h塞线程,使其进 >data->obs="hljs-keywordlock(mutex)
}
ohu-21049-mypl" 进入睡眠,等待 t;used++V b i Q KEY);
oc] inn class="6hu-181 9 k V T(n class="6hu-92t_direct(SYNC_Crdlock(&locpan>, copyable">get ;
ypl" data-mark=件判断之后0 H #unsigbreak; P lock< class="6hu-765? f ( 2 v c on c { 线程之GCD底层原>D j X c U f x4 - On>ck换成e">1.4 全局 allocae a 3 ^span> (data->-mypl" data-marljs-literal">NUs-keyword">if?
...
posix_mema- Z w * :k);
// _RWLock
- (id)i
☞ ier{
NOadcast( h b m r r %1statss="hljs-keywor_lock) { }
};
-span>Lockata->md.lock()
_thrP 9 j g /span>define LOk();
}
}
id objan class="hljs- (m ) [ ConditionLock@k="6hu">3 C d :6hu-11542-mypl"个线程在锁释放 g-19">2. dispatglobal_queue(0,e>nillock];
}
- (;
objcd == 底l var _cond = ffset)
{
r检查。
<)
pthren L . (obj) {}
---------------wift源etCoun"6hu">/ 4 h P ^操作会通过e"id2data cachedata-mark="6hu"s="hljs-keyword="6hu-8250-myplan class="6hu-9ThreadRef?
publpan class="hljsss="6hu-10268-m ? j s N r A条件锁的底r + X I uconlass="hljs-commntptr_t lockCouu-2378-mypl" da饰
oldValue = *span>nit() {ret@"current锁释放时被唤醒 不成立,线程 A 再需要进行加锁 pl" data-mark="有超时
1 O A @ ) Z @ alloc] in d p Xib* id2data( s_cond_init(timespan class="hlj>是一个链表结构EL _cmd, id newi wbject>NULL; p---------------"6hu-18389-myplode>NSLock建一个并发队6hu">I B l 0 K 6 c H Y ( vNSCo [ Z非常种方案比较好呢 h_async("6hu-13039-mypl-function">blic ini// = _MutexPointer,线程会进入休 vConditiata-mark="6hu">an>L_END
7 M W T A,系统在底层维 068-mypl" data-ss="6hu-2553-myspan class="hlju">w = 0 ?ck_init:线程反复检查 加锁的问题。utex)
pthr操作同一个setO过程A L an class="6hu-2表,其中存储了` should get her {
pthread_con<">returnan>urn lR;
} stat2-mypl" data-main">NSObject
首先注意data = result;
/span>做消费者 thread_muterd">switch----class="hljs objn class="6hu-10span>
}
}
_thre= y k R ) Kw_ m # J p meta">#define L"hljs-keyword">="6hu-15561-myps="6hu-9844-mypjectivec copyabif (valuithConditi {
// 如果 pan class="6hu-0">互斥锁
l" data-mark="6s* -(objc_obj/ 9 ? p ] {ment">#########hu-29880-mypl" timeoutMutex)
}ned~ G d t ^ & ...
{
SyncData*mypl" data-markspan>法id,self.num);
被唤醒,而自旋 Count);
0
ord">voidZ } d t F ^
(DebugN象和锁,会按照# K 9 b ^ pog(@ pthre="hljs-comment""6hu-18660-mypl/span>(why) {
<
c D e ? R 3个SyncDatljs-keyword">stread_rwlock_try class="hljs-kephore
类 g-22">4. NSCond多线程编程时, n class="6hu-28不是的,这只能 t
是一个
}
r k X R J ;/class="6hu-2670="6hu">? O O d ent">// Probabl---NC_C*cache = fetch_n>EUE_CONCURREN 9k = [[i++) {
SyncCach
k="6hu">D R i Bf;used;
let _ = lock(w-keyword">voidj a Ban class="6hu-3## .m文件lockCount会消耗掉资R K a j s d A和写的操作,可 pan>];
});
ect *)object-25560-mypl" da/p>
-
.tic +OT_OWNpan class="6hu-an> (data)
-
@ndition: Int, b 0), ^{
an class="6hu-1
}
open rk="6hu">! Z K --------------- R B d 3s-keyword">caseing">"id2data i g J ` RI - P _ ` k SUPPORT_DIRECT">M u Z N O
✅< os(macOS) || oclass="6hu-3366)
mutex.deiniti且性能消耗巨大< W |ue, span>执行下面的lass="hljs-strian class="hljs-量的底层原理, igure>操作在没辑。对同一个线 ass="heading" data-mark="6hu">>NSLoNSLock
(stark="6hu">{ _ Mjs-keyword">if<4304-mypl" datad_signal(cond)
/code>方| O [iveLock,而又需" data-mark="6h="6hu-29470-myp
}
OSAt">n 2 Uo到关于atoan>OS底层学习 -t(data);
dY h E 0 &// d线程之中的锁🔐"hu-13392-mypl" ta-mark="6hu">b传入一个想要加 span class="6hus="6hu-25584-my6hu-37140-mypl"l_queue(DISPATC( . ~ 2 ) 6(-image-4405" ti, [ x T 1)
private var -built_in">NSObpre>// 如果获取到 mutexattr_setty"6hu-33795-mypl没有读者,也没 data-mark="6hu"ache->used].是一种锁下的不 span class="hljn class="hljs-bark="6hu">M * $的实现逻辑中, s block
tex_lock(timeou *)key{
__block程,但是N成了线程 1 等线ead A:%ldn"
}
0
s="6hu-36074-my,不会进行多次 ,那么就会来到 n.h>
cachopen SData* resultX R F ( A H } pan> {
; i < tesss="hljs-built_pan class="hljsl" data-mark="6n class="hljs-belf .tick看可得
r( 6 k K /p>
因为这个34-mypl" data-m _ % f e>
_cond.lock()
pl" data-mark="mark="6hu"> Z }前Q 9 a Q ypl" data-mark=/code>状态下使 么他就存在着一 k];
});
-------h2 class="headi---------------解锁操作代码
[co
*nditionLock
具体用法16">1.3 检查有 class="6hu-2755s="hljs objectia-mark="6hu">B
-
nexs buggy"62-mypl" data-msync
的方2_t threadCount="6hu">- R L4 L g y q yata-mark="6hu">an>.init(conditpl" data-mark="ss="6hu-28779-m>object = (oh ] ) P ( }01! ng" data-id="he lnil();可能造成高优先 B ^;
}
an>其代
{
=习 - 多线程之中的调度开销,因 _cond.unlock()
>休眠状态,而不n class="6hu-176-mypl" data-ma线程之GCD应用篇了#if SUPPORT_Dan>Pointer.allo-mark="6hu">0 I00-mypl" data-m # 9,可 ">if (re"6hu">p * %否则读 k];
};
t1l" data-mark="6yword">for
NSspatch_queue_cr
}
open lass="hljs-comm/span>ggy")
pthrspan class="hljhu-16849-mypl" 1253-mypl" data5 * w y D / r iclass="6hu-2584pe(attrs, Int32n class="6hu-37dCount &lnil
_vring">"Thread Bmypl" data-mark素,只有在大于0n> result = OBJg");
}
oata-mark="6hu"> Y : )ba = 0; iN2 x H<A =">NSLog(lass="6hu-32000-mark="6hu">z Cn> 准备Sylass="6hu-30485常开发中较少使 span> lock(befo产一个 现有 cou效果。
TEX_RECURSIVE)l" data-mark="6ark="6hu"># = 0ing" data-id="h {
这个
tlock = ck(timeoutMutexr (int irk=" 6hu"="">H 0 / ord">id 保证多个线程对 /span>
}
open v-mark="6hu">| ~mypl" data-mark俩讲解。
将上rent_queue = diastCacheOccupiehenCondition: c
✅(m A r I F J 6rk="6hu">u : 4 data-mark="6hul" data-mark="6a-mark="6hu">| 步读取指定数据:= Rool a>
cache->lis {
Selass="6hu-12220为NSCondition可lock(timeoutM需要将线变0tex.dealloca且能够解决&js-number">0J N" data-mark="6hR J 1"U O C M v 进⾏读写的机制 number">100
SyncCache span>() {
pthre="6hu-2607-mypl的锁🔐" alt="iO}
来保护线程安全 >可以试想一下,x
互斥锁 open fustructk="6hu">c W h W。
- 是 l>
rk="6hu">x N y " data-mark="6h6351-mypl" data/span>imeoutCon-keyword">case<_inform(H P W Rt->object = um = self.num +k="6hu">H 0 / 2returna* data pl" data-mark="pan class="6hu-锁,直⾄显式释 (dispatch_get_g @synchronized("hljs-comment">ta-mark="6hu">} class="hljs-kede>SyncList,mark="6hu">; _ ass="6hu-37056-span class="hljomment">#includ发现,在---------了os_unfaV 7 Q X d Relse
A / * I _ } I< class="hljs-ke关联的锁
ng-25">总结<"6hu">e & I i 9
[_cx X pan class="6hu-hu">/ W c ~read cach点和一个in">NSRecursiven>进行就是实现 ;
void y collid"6hu-19272-mypl作,那么就不能 ss="6hu-9450-my"hljs-comment">">= E W ~ [ ,3. NSLock操作时,会先从 ck: NSObject, Nyword">int自旋锁 ck per-thread s6hu-14022-mypl"ilt_in">NSCondi>;
it,则对 loc// 原子属性,加a-mark="6hu">q code>c usage why)
据相同
return
int">= z W s="6hu-23332-my⼀过程中保持执 写-加锁
pthreidE o ; yif
(!f程单项快速缓存 短时间的场OSSpinL
@syt*)// @synljs-comment">#iyword">ida , ) Ned的相关操作已 sult = OBJCg-mark="6hu">E ban class="6hu-2pan class="hljs k L testlock unlo<",value))
}
open func `an class="hljs-C 5 + c/mypl" data-markt">// 检查已拥 学习,我们对整 ">a 3 t = R f //Threak="6hu">! - , 4向下进行。这个 "6hu-25746-myplan>我们1,s件锁。
pl" data-mark="0) {
{ mark - 读数据, ;
}
ta-mark="6hu">h12342-mypl" dat"6hu">= 3 [源码在n>
*listp = resspan class="6hude>的线程安全,data-mark="6hu"a-mark="6hu">6 eyword">intelse
- (void)wytCond)
pthread_eak;
}
// 致性能较高,而 >mutexa等方法<: c iabls="6hu-8284-myp问,写者则需要 s-literal">nil<= 8 ;可 word">elsety(id secrease l" data-mark="6og( returnn>
)lockCount);u-245-mypl" dat转后,高优先级 kWhenCondition:ljs-keyword">ca者re_ & | -,和dispal )
}
opet value = %dyncData
SyncData`结构的n class="hljs-c="6hu-21840-myp
fastCachen class="hljs-c obj)
{
} a * J / ` @ n class="hljs-n class="6hu-585---------------一种互斥锁,但 h ! . u k {
internaark="6hu">9 u |线程也会造成影 rk="6hu">o x O锁的是 n>
tls_set_direspan>)consumenum7 S +span class="6hut/uploads/2020/ ! z t M但没有获取到时 c ( ; --->
+;
q @ F b R # 0-------ss="hljs-keyworspan>, g
那么这种js-number">1falseX L ? y U tpan class="6hu-6hu-27587-mypl"ss="hljs-literau">~ a { 4: , p d">void >testMetdata-mark="6hu"⾏写操作。这种 s-number">0false☞ iOS底^ W ? W vNSC g i B Ypan>ata
;
result->thhu">Y i h m 7 5mic
相关 l" data-mark="6="heading-21">3>q q c H h J Q I 2 z很 ---------------
-
NSCu">3 l P R F t 结M能造成提前释放 pan>TY_HIGH, 锁的 ypl" data-mark=ondition: Int) ol {
data-mark="6hu"nt">// 如果obj 指的是链表S 8 1 8 O ~ u">2 4 5 inline void rek="6hu">~ ] c ae = *slot;
*sl<-mark="6hu">y Fd">if (r我们看Swi/span>Count)static我们经常-keyword">ifI . y U $ 1 @="6hu">Z S : G 8ists[oLockCPU全。
当 fore: Date.disthe->used];
) does nothi占用时间片。hCondition co11480-mypl" datan class="hljs-an>中下一个元素EASE) {
)
public an>acheLineSizespan class="hljirstUnused = (why == REL{
_value = condclass="hljs-numn class="6hu-25/span>ttr_init(k="6hu">C w j n>Key:(NSString (obj) {ING_THREAD_ERROint objccopyable">open pan class="6hu-span>.ticketCou # Q n Q O,NSLoc结接进行赋值,如 -2929-mypl" datumber">0" data-mark="6han>------------2 5 N - j Z eli>
mutex>^literal">NULLL,<关),但不能同 的 ACQUILists;一下@synchljs-keyword">r-28782-mypl" da/span> SyncDatade>的方式进行增6hu-880-mypl" d G
onizedipedMap<Syncead_mutex_init(pan>
了
的头 ? Q 1 * = U `f U U u _ h - 现,应该也是差 任务,没有占用 _t mutex;
} Syndata-id="headin-mark="6hu">@ &锁为什么安全NSLpl" data-mark="
nil共gnal()锁,即可以递归 一直处于等待状 word">self, ljs-comment">#pan class="6hu-3中的一个元素。 4 程则会 concurrent RELElass="6hu-28182e d ) ? i a % ,_in">NSLog; i < cachen class="6hu-10ove from per-th常流程
[无法抢占时间片 mark="6hu">} } "hljs-keyword">"hljs-comment">ljs-comment">//常用锁总结:当 patch_get_globan func lock() {" data-mark="6hass="6hu-740-mycode>结果中,进read !cast() {
特殊的⾃旋锁ass="hljs-literkWithCondition:ass="6hu-29648-span class="6hu data-mark="6hucode>。
roy(mutexe why)
{
...
.ink="6hu">T p . _value
J } @ B [ J J< 2 等线程 1 解 bleDictionary dst thread cachepl" data-mark="0-mypl" data-maeallyintf x ;NS B L
pth4080-mypl" data没有起到加锁的 class="hljs ob安全的时// 所有 6050-mypl" dataR 2 Q z待的线程,需要 ata-id="heading经执行完成。总 class="hljs-limark="6hu">u ~ code>是对hu-34153-mypl" 都能code>。我们可以nt">// 如ock code>SyncList` K m o N<查询和缓存
open func lockclass="heading" class="hljs-kenlock_t& slypl" data-mark=-mark="6hu">t mqueueOS底层学习 - 多s="6hu-24108-myl" data-mark="6-literal">NULL<0="6hu-24434-mypt; sDatain
p的是要有一个出 /span>lt = firscData
Symypl" data-mark否则无法进行锁 value = objc_re->us: limit) ck()
lock
至此NUL// Wakeuphu"> s =">0) {
开辟了多条线mark="6hu">u o "6hu">& , _ cKey:(NSStrispan class="hljhu">k + I C G )] ( _ecteMutableq 有超时时,会阻 -keyword">ifch_asynceral">NOcking {
"hljs-keyword">n>el缓存线程-&;
✅e u l0 T 5 多线程之GCD队 hu-20790-mypl" data-mark="6hu"data-mark="6hu"/span> (!okay) [[基础小 a-mark="6hu">4 code>get & i snLmypl" data-marknit(timeoutCondg H;unloass="6hu-8256-mu-17458-mypl" dlocksdispa V e j ; D o } hu">l h r 6 ` d">j [ B q B mning ,否则无法加锁。 2-mypl" data-ma h x u p kt y>ch.
res状态的高优先级 :
法来实现加锁 9r.alloc---------------an class="hljs-ta-mark="6hu">L>ync(dis="6hu-11232-mypta-id="heading-irect(SYu iass="6hu-15687-/span>程& ^ C _ Z #n>t;
}
x)
pt/code>是N-mypl" data-marpan>
1mark="6hu">p ? S Srrens="6hu-17199-mypan class="hljsapacity: ject如果上述两 de>的底层原理是* ) g 2 m tockCC data-id="headin/span>ursive AC4-mypl" data-ma endTime: limit>进行了捕获和释接返回值
等条件 C 成立h_get_global_quache->list[c_objectForKey:((="6hu">| b 3 s slot;
*slot = n 用递归 l" data-mark="6释放后才能再次returan>->看☞i层原理篇
falseu-33959-mypl" d )
// Ch
对于 data-mark="6hutch_sf f + *>| Z t p Qlot];
6hu-21395-mypl""6hu-22473-mypln>he.
ui高速缓存中是否 u">) N $ n $ V取到单个线程中 ypl" data-mark=t; object;
int3an class="hljs-果是的话,会加 aches above.
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)