|
1inumcubo2p6405520.gif
) G. z1 \4 X3 F0 C7 H! V
点击上方蓝色字体,关注我们: S" }7 B3 z' A* ?1 w! D7 N
" e1 y f4 X3 ]8 _5 I+ g8 ^
共享资源指的是多个线程可能会同时读取或修改的变量或数据结构。
5 [1 u! G k' H2 T/ \& H* W8 l U, S2 ?! r
举个例子,如果有一个全局变量 a,线程1和线程2都在对这个变量进行读写操作,a 就成为了它们之间的共享资源,多个线程都需要访问它。: X9 q% l0 n, ?& ^, R9 }, g
$ v9 f2 B- `1 a) Z; `) W+ S; L
数据不一致的根本原因在于多个线程对共享资源的并发访问。
2 x( G$ [. B/ W# }
# F" L) @" H! X5 Z+ H' b线程在操作系统中是并发执行的,它们可以在任意时间被操作系统调度。" R3 C# n( B& _* k8 H- }3 [( T+ e
" e d+ V* T- `$ R( V( `; k. @因此,多个线程可能同时对某个共享资源进行操作,而这种并发操作就会导致竞争关系的产生。8 b7 {. Y4 a& w
0 ], B n R+ u4 Z4 R9 \就像现实生活中的竞争一样,多个线程“争夺”对共享资源的控制权。
; p" R+ T {' m: L6 j
. I' `$ Y; }- d3 I# v2 {& _如果一个线程正在修改某个共享变量,另一个线程同时读取该变量,它可能会读取到一个错误或者不完整的值。5 ?. k2 B8 k. L8 b; X
1' r! @5 j) m# N8 u; j5 ~" \9 c5 g
什么时候需要线程同步?* N# o5 Z6 K' J8 J% ~; d9 q3 N
并非所有情况下都需要线程同步,只有在以下几种情况时才需要:/ H a' S" N$ ^% Q2 |
多个线程会修改共享资源:如果一个线程修改某个共享变量,其他线程可能也会修改或读取该变量,这时数据一致性问题就可能发生。比如线程1修改了变量 a 的值,但线程2在修改未完成前读取了 a,结果就会导致线程2获取到一个不正确的值。共享资源的写操作是非原子的:很多时候,修改共享资源的操作不是一个瞬时的、不可中断的过程,而是需要多个步骤完成的(如读-改-写的操作)。如果在这些步骤之间有其他线程介入,对同一个共享资源进行操作,就会产生不一致的结果。# V: v6 o, p6 H: H% U) H0 s( w
2
. S: Y) Y6 v: s什么时候不需要线程同步?, F- Q% \1 R3 z" `
如果变量是局部变量(只在某个线程的作用域内),或全局变量但只有一个线程访问它,那么不需要担心数据一致性问题。如果变量是只读的,多个线程同时读取不会造成问题,因为它们不修改数据。
- D) ]/ o0 v% n3 ?& a2 u3 s; R
/ O2 l+ E! g8 |! G7 a假设有两个线程A和B,它们都在访问同一个共享变量x。
6 j' R0 J/ j4 M/ k; O
5 v* z2 l# ?$ D$ [8 o( h线程A先读取变量x的值,然后准备将新的值写回x。
/ p5 v) T$ G* h" a
2 u5 p1 `2 `+ g: Y5 b9 z假设写操作需要两个时钟周期完成,但在写操作还没完成的过程中,线程B恰好读取了变量x,此时线程B会得到一个旧的值,而不是预期的正确值。! X* y! e) U8 b% @0 U' Y
* }4 u r6 \7 B; x& l0 D这种情况下,就会导致数据不一致。
% @; Z: r A0 m
5 W" W' d3 c3 a8 ~5 {
k30ymlevtir6405620.png
# X& M$ w6 Y5 p3 ^5 z
0 g; G3 |( T! U* }5 L为了避免这种情况,我们引入线程同步机制。: X! _1 u" Z O4 B9 B
! ]! C" F- ^& U
同步可以通过互斥锁(Mutex)、信号量(Semaphore)等方式来实现,确保同一时刻只有一个线程能够修改共享资源,防止数据在并发访问时出现异常。
- w/ V* ~- t/ |8 L- X% f- H v
3 N0 g4 Z% b* ?9 K& I这些机制可以有效解决资源的竞争问题,确保每个线程在访问共享资源时,都能够获得一致的状态。2 H- T0 w3 k: R9 p1 B! ?# o! y
izuqceemewi6405720.jpg
; v! O+ B' k# ^; g6 Y4 D1 T |
fnpp1w2q5ir6405820.gif
+ e _+ }5 ^3 u9 J
点击阅读原文,更精彩~ |
|