Hey guys...so I m试图冲上我的C楼,我发现的一个问题是:
鉴于全球变量x = 0;执行功能真空无用(int n),该功能产生线形状,在 lo状增加×1时,每read在X达到100时终止。
我只靠read子处理,需要一个牢固的榜样来奠定我的基础。 这必须尽可能使用校对系统。
Hey guys...so I m试图冲上我的C楼,我发现的一个问题是:
鉴于全球变量x = 0;执行功能真空无用(int n),该功能产生线形状,在 lo状增加×1时,每read在X达到100时终止。
我只靠read子处理,需要一个牢固的榜样来奠定我的基础。 这必须尽可能使用校对系统。
首先,你们需要决定你们想要达到什么目标,不同路面的指令可以如何避免出现这种情况。
Cx<>x
的增量操作者通常被采用为从记忆到登记册的价值;增加登记册;写记:
r1 ← xglobal r1 ← r1 + 1 xglobal ← r1
因此,x全球的价值被一加一。
如果你同时有两条read子,那么他们就会受到毁灭性干扰。
initial xglobal = 99 r1 ← xglobal compare r1 100 r2 ← xglobal compare r2 100 r1 ← r1 + 1 == 100 r2 ← r2 + 1 == 100 xglobal ← r1 == 100 xglobal ← r2 == 100 r1 ← xglobal compare r1 100 stop r2 ← xglobal compare r1 100 stop final xglobal = 100
因此,x全球值被一加一,尽管二者都read了。
(我略去说明ach具的影响,这意味着阅读2版的变数时,即使正好一字的书写在墙壁上读之前发生,也可能发生。) 寻找和释放胎面中的mut子,造成记忆障碍,迫使所有人在行为发生后和书写行为,就像在取得或释放之前发生。 iii
(以上为for(t r; r = x ) < 100;x = r + 1 )
,而不是for(;x < 100;x = x + 1 )
,后者可读到x,因此,还有另一个点,read可以干预......)
同样,一对一线的加固可摧毁另一条透镜的加固,使胎面与i <相平;100:
initial xglobal = 98 r2 ← xglobal r1 ← xglobal compare r1 100 r1 ← r1 + 1 == 99 xglobal ← r1 r1 ← xglobal compare r1 100 r1 ← r1 + 1 == 100 xglobal ← r1 r1 ← xglobal compare r1 100 stop compare r2 100 r2 ← r2 + 1 == 99 xglobal ← r2 ... final xglobal = 99
因此,左胎表面的第二次加热,在第一次加热时已经过时,而且会以全球可见的x <值终止;100。
你们可能知道这一切,并可能希望利用一种机制来防止这种情况。
我可以说,你的要求是明确的——在X达到100时,上文的线索即告终止;这些要求并没有说它这样做。
因此,由于没有书面Xglobal ← 100,实际上可以在不设锁的情况下满足这一要求,但<代码>x<>>>>x 可加添<>n*100倍而不是100倍。 (如果该限额大于按部就班,则X的书写在某些平台上可能不会进行分类,如果来自不同透镜的tes合在一起,可能会造成一种无限的 lo,但只有100的宽度达到一定点。)
一种技术是使用mutex ,其中把其他透镜从一对read在路面上锁时停下来。 如果在x全球<>之前获得这一锁,在x全球<><<><><><><<><<>>>书面之前不予以发放,那么该read的读本和写便不可相互分离。
initial xglobal = 98 lock (mutex) mutex locked lock(mutex) blocked r1 ← xglobal compare r1 100 r1 ← r1 + 1 == 99 xglobal ← r1 release ( mutex ) mutex locked r2 ← xglobal compare r2 100 r2 ← r2 + 1 == 100 xglobal ← r2 release ( mutex ) lock (mutex) mutex locked r1 ← xglobal compare r1 100 release ( mutex ) stop ... final xglobal = 100
在校外,您不妨利用平台的比较和互换操作(_sync_val_compare_and_swap
in gcc ),该平台处理旧价值和新价值,并在新价值相同的情况下将原有记忆与新价值挂钩。 这让你把逻辑写成:
for ( int v = 0; v < 100; ) {
int x_prev = __sync_val_compare_and_swap ( &x, v, v + 1 );
// if the CAS succeeds, the value of x has been set to is x_prev + 1
// otherwise, try again from current last value
if ( x_prev == v )
v = x_prev + 1;
else
v = x_prev;
}
因此
initial xglobal = 98 initial v1 = 0 initial v2 = 0 cmp v1 100 x_prev1 ← CASV ( xglobal, v1, v1 + 1 ) = 98 ( set fails with x == 98 ) cmp v2 100 x_prev2 ← CASV ( xglobal, v1, v1 + 1 ) = 98 ( set fails with x == 98 ) v1 ← x_prev1 = 98 // x_prev != v v2 ← x_prev2 = 98 cmp v2 100 x_prev2 ← CASV ( xglobal, v1, v1 + 1 ) = 98 ( set succeeds with x == 99 ) v2 ← x_prev2 + 1 = 99 // as x_prev == v cmp v1 100 x_prev1 ← CASV ( xglobal, v1, v1 + 1 ) = 99 ( set fails with x == 99 ) v1 ← x_prev1 = 99 // as x_prev != v cmp v1 100 x_prev1 ← CASV ( xglobal, v1, v1 + 1 ) = 99 ( set succeeds with x == 100) v1 ← x_prev1 + 1 = 100 // as x_prev == v cmp v2 100 x_prev2 ← CASV ( xglobal, v1, v1 + 1 ) = 100 ( set fails with x == 100 ) v2 ← x_prev2 = 100 // as x_prev != v cmp v1 100 cmp v2 100 stop stop
每一次休息室,xglobalatomically 如果并且只有在其先前的价值为1>+1>时,才将其数值定为<>/sub>;如果没有,则将“1> = 化学文摘社登记系统运行期间测试的xglobal数值。 这减少了大多数执行阶段的锁定时间(尽管在化学文摘社运行期间仍需要锁定记忆公共汽车,但只有这些行动将进行序列化。 由于在多个核心领域执行化学文摘社费用昂贵,因此,这种简单案例可能胜诉。 iii
You need a mutex to protect the variable. Each thread will lock the mutex, increment the variable and release the mutex. Each thread that doesn t do this is a rogue thread.
你们需要的是一个关键部分。 在窗户下,这将成为立体科,但在校正环境中,等同物是pthread_mutex_lock<>。 见here。
我认为,如果“X >”能为每一条read子出走,则“InterlockIncrement”就足够了。
我永远不会使用一个关键部分,除非我确实不得不这样做,因为这可能导致大量争论。 洲际水泥公司根本不存在争议,至少不会影响所有业绩。