में एक डबल फाड़ना अनुकरण करें मैं 32-बिट मशीन पर चल रहा हूं और मैं यह पुष्टि करने में सक्षम हूं कि लंबे कोड निम्न कोड स्निपेट का उपयोग करके फाड़ सकते हैं जो बहुत जल्दी हिट करता है।सी #
static void TestTearingLong()
{
System.Threading.Thread A = new System.Threading.Thread(ThreadA);
A.Start();
System.Threading.Thread B = new System.Threading.Thread(ThreadB);
B.Start();
}
static ulong s_x;
static void ThreadA()
{
int i = 0;
while (true)
{
s_x = (i & 1) == 0 ? 0x0L : 0xaaaabbbbccccddddL;
i++;
}
}
static void ThreadB()
{
while (true)
{
ulong x = s_x;
Debug.Assert(x == 0x0L || x == 0xaaaabbbbccccddddL);
}
}
लेकिन जब मैं युगल के साथ कुछ ऐसा करने की कोशिश करता हूं, तो मैं किसी भी फाड़ने में सक्षम नहीं हूं। क्या किसी को पता है क्यों? जहां तक मैं कल्पना से बता सकता हूं, केवल एक फ्लोट के लिए असाइनमेंट परमाणु है। एक डबल के लिए असाइनमेंट को फाड़ने का खतरा होना चाहिए।
static double s_x;
static void TestTearingDouble()
{
System.Threading.Thread A = new System.Threading.Thread(ThreadA);
A.Start();
System.Threading.Thread B = new System.Threading.Thread(ThreadB);
B.Start();
}
static void ThreadA()
{
long i = 0;
while (true)
{
s_x = ((i & 1) == 0) ? 0.0 : double.MaxValue;
i++;
if (i % 10000000 == 0)
{
Console.Out.WriteLine("i = " + i);
}
}
}
static void ThreadB()
{
while (true)
{
double x = s_x;
System.Diagnostics.Debug.Assert(x == 0.0 || x == double.MaxValue);
}
}
बेवकूफ सवाल - क्या फाड़ रहा है? – Oded
इनट्स पर संचालन कई थ्रेडों के उपयोग के संबंध में परमाणु होने की गारंटी है। इतने लंबे समय तक नहीं। फाड़ना दो अंतरिम मूल्यों (बुरा) का मिश्रण हो रहा है। वह सोच रहा है कि युगल में ऐसा क्यों नहीं देखा जाता है, क्योंकि युगल भी परमाणु परिचालन की गारंटी नहीं देता है। – hatchet
@ ओडेड: 32 बिट मशीनों पर, केवल 32 बिट्स एक समय में लिखे जाते हैं। यदि आप 32 बिट मशीन पर 64 बिट मान लिख रहे हैं, और उसी समय एक ही पते पर दो अलग-अलग धागे पर लिख रहे हैं, तो आपके पास वास्तव में * चार * लिखते हैं, * * * नहीं, क्योंकि लिखते हैं 32 बिट्स एक वक़्त। इसलिए धागे दौड़ने के लिए यह संभव है, और जब धूम्रपान चर को साफ़ करता है तो एक थ्रेड द्वारा लिखे गए शीर्ष 32 बिट्स और दूसरे द्वारा लिखे गए 32 बिट्स होते हैं। तो आप 0xDEADBEEF00000000 को एक थ्रेड और 0x00000000BAADF00D पर दूसरे पर लिख सकते हैं, और मेमोरी में 0x0000000000000000 के साथ समाप्त हो सकते हैं। –